我有一个变量 char *cmd,我想从 fgets() 中存储一个字符串。有没有办法使用 malloc 或类似的东西为这个变量动态分配内存?还是我必须预先定义它的大小并在之后终止?之前,我将 cmd 的大小预定义为 100,但我试图找出出现分段错误的位置。
char *cmd;
fgets(cmd, n, stdin);
然后我尝试使用带有空格作为分隔符的 strtok() 来标记 cmd 字符串。
我有一个变量 char *cmd,我想从 fgets() 中存储一个字符串。有没有办法使用 malloc 或类似的东西为这个变量动态分配内存?还是我必须预先定义它的大小并在之后终止?之前,我将 cmd 的大小预定义为 100,但我试图找出出现分段错误的位置。
char *cmd;
fgets(cmd, n, stdin);
然后我尝试使用带有空格作为分隔符的 strtok() 来标记 cmd 字符串。
正如我在上面的评论中所说,这不是标准 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;
}