我有一个从stdin读取字符串的函数,它基于answer from here,
char* ReadString (FILE* f) {
int chr;
int n=0;
size_t size=4;
char *st=(char*)malloc(size*sizeof(char));
while (((chr=fgetc(f))!='\n') && (chr != EOF) ) {
st[n]=chr;
if (n+1==size)
st=(char*)realloc(st,(size+=8)*sizeof(char));
n++;
}
st[n]='\0';
return (char*)realloc(st,sizeof(char)*n);
}
好的功能正常,但我发现了一个问题。
int k;
printf("number\n");
scanf("%d",&k);
while (!loop) { //infinite loof for tests
printf("Name of the file and distination\n");
fname= ReadString(stdin);
printf("\"%s\"\n",fname);
}
现在我会遇到分段错误。那么问题,据我所知,是在scanf之后,在stdin" \ n"离开了。如果我把
while ( getchar() != '\n' ); // clean stdin
fname= ReadString(stdin);
我不会得到分段错误,第一个字符串将完全读取,但下一个字符串将无法正确读取我将需要输入两次。 为什么(((chr = fgetc(f))!=' \ n')&&(chr!= EOF))不起作用? -------------回答--------------
根据以下答案,这里是未来的代码。
char* ReadString (FILE* f) {
int chr;
int n=0;
size_t size=4;
char *st=(char*)malloc(size);
bool loop=false;
while (!loop) {
while (((chr=fgetc(f))!='\n') && (chr != EOF) ) {
st[n]=chr;
if (n+1==size)
st=(char*)realloc(st,(size+=8)*sizeof(char));
n++;
}
loop=true;
if (n==0)
loop=false;
}
if (n!=0 )
st = (char*)realloc(st,sizeof(char)*n);
st[n]='\0';
return st;
}
答案 0 :(得分:1)
您上一次realloc
中有一个错误的错误。您的字符串存储n+1
个字节,但您将分配缩短为n
个字节。
如果读取的第一个字符是换行符,则循环永远不会运行。您的st
字符串由0个字符组成,后跟'\0'
终结符,即它使用1个字节的存储空间。
但n
是0
,所以realloc(st,sizeof(char)*n)
将其重新分配到0字节,这可能会释放字符串(或返回指向0字节内存的指针,不得取消引用)。
最简单的解决方案是return st
而不重新分配它。否则它应该类似return realloc(st, n+1);
(但您应该检查所有realloc
次调用中的错误。)