C 有没有一种方法可以动态设置从fgets()获取的字符串的大小?
我有一个变量char*cmd,我想在其中存储一个来自fgets()的字符串。有没有一种方法可以使用malloc或类似的方法为这个变量动态分配内存?或者我必须预定义它的大小并在之后终止null吗? 以前,我将cmd的大小预定义为100,但我试图找到分段错误的位置C 有没有一种方法可以动态设置从fgets()获取的字符串的大小?,c,dynamic-memory-allocation,fgets,C,Dynamic Memory Allocation,Fgets,我有一个变量char*cmd,我想在其中存储一个来自fgets()的字符串。有没有一种方法可以使用malloc或类似的方法为这个变量动态分配内存?或者我必须预定义它的大小并在之后终止null吗? 以前,我将cmd的大小预定义为100,但我试图找到分段错误的位置 char *cmd; fgets(cmd,n,stdin) 然后,我尝试使用strtok()对cmd字符串进行标记,并使用空格作为分隔符。正如我在上面的评论中所说的,这不是标准C的内置功能,尽管有一个POSIX函数可以实现您想要的功能
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;
}
#包括
#包括
#包括
//注意:dygetline()分配内存!不要忽视回报和回报
//完成后记得把它放出来!
#定义BSZ 1024
char*dygetline(文件*限制流){
char*ret=NULL;
char*temp=NULL;
尺寸=1;
字符缓冲区[BSZ];
尺寸_tbuflen=0;
char*nlsrch;
while(NULL!=fgets(缓冲区、BSZ、流)){
nlsrch=strrchr(缓冲区“\n”);
if(nlsrch)*nlsrch='\0';//如果存在,请删除换行符
//获取读取缓冲区的大小并增加返回缓冲区
buflen=strlen(缓冲区);
温度=realloc(ret、retalloc+buflen);
如果(NULL==temp){
fprintf(stderr,“dygetline()中的内存分配错误!”\n);
免费(ret);
返回NULL;
}
ret=temp;//更新返回缓冲区指针
strcpy((ret+retarloc-1),buffer);//将读取缓冲区添加到返回缓冲区
retarloc=retarloc+buflen;//内务管理
if(nlsrch)break;//如果有换行符,请停止
}
//如果出现文件读取错误,并且fgets()从未获得任何信息,则
//ret在初始化时仍然为空。如果文件结束
//如果没有尾随换行符,则ret将包含它所包含的所有字符
//能从最后一行得到。否则,它应该是好的-
//形成。
返回ret;
}
没有内置的语言功能,但是如果fgets()
不能一次获得完整的行,就不能阻止动态分配缓冲区并根据需要增加缓冲区。您可以通过fgets()
使用的缓冲区中的最后一个字符是否为换行符来判断。您可以将固定大小的字符串传递给fgets()
。查找POSIXgetline()
,查找根据需要分配空间的行读取函数;然后是fgets(cmd,200,stdin);但是当使用strcopy()将cmd存储到char pointer*标记中时,我遇到了一个分段错误;他们指着琴弦。“但我一直在试图找出我在哪里遇到了分段错误。”-发布您的尝试,我们很乐意提供帮助,但现在,S.O.水晶球出问题了。。。您的问题中存在多个问题(1)是否有一种方法可以分配或我是否需要使用fgets
的固定buf-您可以这样做,但您必须在调用fgets
之前分配或声明固定buf;(2) 塞格断层;(3)在空白处使用strtok
标记(不要忘记行尾是空白)。请提供。注意:strrchr()
和strlen()
对缓冲区的n
字符进行两次传递。只有strlen(缓冲区)
才能找到一个潜在的'\n'
并知道长度。retaloc+buflen
太小了。建议realloc(ret、retalloc+buflen+1)代码>strcat(ret,buffer)代码>随着每次连续的串联而逐渐变慢。如果(retalloc==0)ret[0]='\0',只需删除它并替换代码>带有strcpy(ret+retarloc,缓冲区)代码>或memcpy(ret+retarloc,buffer,buflen+1)代码>我们只需要一个空终止符,无论我们经过多少次fgets()
,因此在1
处启动retarloc
应该可以做到这一点,而不是每次调用fgets()
时都增加一个字节。不过捕获效果不错。if(retalloc==1)ret[0]='\0'代码>是不需要的。(和realloc(ret,retarloc+buflen+1)
不会“每次增加一个额外字节”)。还是很好的升级。