0

我有一个变量 char *cmd,我想从 fgets() 中存储一个字符串。有没有办法使用 malloc 或类似的东西为这个变量动态分配内存?还是我必须预先定义它的大小并在之后终止?之前,我将 cmd 的大小预定义为 100,但我试图找出出现分段错误的位置。

char *cmd; 

fgets(cmd, n, stdin);

然后我尝试使用带有空格作为分隔符的 strtok() 来标记 cmd 字符串。

4

1 回答 1

1

正如我在上面的评论中所说,这不是标准 C 的内置功能,尽管有一个 POSIX 函数可以满足您的需求。如果你想自己动手,方法是动态分配(和重新分配)内存来存储你从fgets(). 您可以判断何时fgets()到达行尾,因为它会突然到达文件的末尾(在这种情况下它将返回NULL)或者因为它返回的最后一个字符将是换行符。

这是一个示例函数。请注意,我使用strrchr()从缓冲区末尾向后搜索换行符。如果命中,我们确保在返回的字符串中丢弃换行符,并确保跳出while()循环,这样我们就不会fgets()再次调用并开始获取下一行。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// NOTE:  dygetline() allocates memory!  Do not disregard the return and
// remember to free() it when you're done! 

#define BSZ 1024

char *dygetline(FILE * restrict stream) {
  char *ret = NULL;
  char *temp = NULL;
  size_t retalloc = 1;
  char buffer[BSZ];
  size_t buflen = 0;
  char *nlsrch;


  while (NULL != fgets(buffer, BSZ, stream)) {
    nlsrch = strrchr(buffer, '\n');

    if (nlsrch) *nlsrch = '\0';     // Remove newline if exists

    // Get the size of our read buffer and grow our return buffer
    buflen = strlen(buffer);
    temp = realloc(ret, retalloc + buflen);

    if (NULL == temp) {
      fprintf(stderr, "Memory allocation error in dygetline()!\n");
      free(ret);
      return NULL;
    }

    ret = temp;                     // Update return buffer pointer

    strcpy((ret+retalloc-1), buffer);  // Add read buffer to return buffer
    retalloc = retalloc + buflen;      // Housekeeping

    if (nlsrch) break;              // If we got a newline, stop
  }

  // If there was a file read error and fgets() never got anything, then
  // ret will still be NULL, as it was initialized.  If the file ended
  // without a trailing newline, then ret will contain all characters it
  // was able to get from the last line.  Otherwise, it should be well-
  // formed. 

  return ret;
}
于 2018-12-09T02:24:58.867 回答