在C中创建get string函数时遇到的问题
我正在尝试创建一个简单的函数,以安全的方式返回字符串,我想知道这段代码有什么问题。在C中创建get string函数时遇到的问题,c,string,stdin,cs50,C,String,Stdin,Cs50,我正在尝试创建一个简单的函数,以安全的方式返回字符串,我想知道这段代码有什么问题。 我决定使用read,因为scanf和fgets都给e带来了麻烦, 具体地说,如果我在进行长度检查时缓冲区溢出,scanf会给出中止陷阱6, 当fgets接受输入时,如果插入的字符串太长,则返回错误消息,但无论如何都要预翻转该字符串,而不允许我重新输入另一个字符串。 代码如下: string get_string(const string prompt) { char temp[30]; int s
我决定使用read,因为scanf和fgets都给e带来了麻烦, 具体地说,如果我在进行长度检查时缓冲区溢出,scanf会给出中止陷阱6,
当fgets接受输入时,如果插入的字符串太长,则返回错误消息,但无论如何都要预翻转该字符串,而不允许我重新输入另一个字符串。
代码如下:
string get_string(const string prompt)
{
char temp[30];
int size,count;
printf("%s",prompt);
do
{
count=read(0,temp,29);
temp[count]='\0';
size=strlen(temp);
if(size>24)
{
printf("\x1B[31mError\x1B[0m: too long.\n%s",prompt);
}
printf("size :%i\n",size);
}
while(size>24);
stripc(temp,'\n'); //removes new line
string word=malloc((size)*sizeof(char));
strcpy(word,temp);
return word;
}
现在使用read时,它会给我类似的错误,我从stdin读取了总共30个字节,然后我在计数器的末尾添加null字符,但如果长度超过,则输出为:
ppppppppppppppppppppppppppppp
Error: too long.
size :30
size :2
p
知道问题出在哪里吗?有没有其他方法来实现我的需求 编辑:问题没有超出范围,
奇怪的是,一旦我写了超过24个字符,
应该读取输入(读取、扫描、fgets或其他)的函数,
不再激活,这就是为什么size:连续出现两次,
由于某种原因,输入插入被跳过,我想了解原因。
我更正了一些错误。如果在第一次输入中没有找到换行符,请调用fgets,直到找到换行符,以便清理输入流,然后继续外部while循环
string get_string(const string prompt)
{
char temp[26] = "";//24 + newline + '\0'
int size,count;
while ( 1)
{
printf ( "%s",prompt);
if ( fgets ( temp, sizeof temp, stdin)) {
if ( !strchr ( temp, '\n')) {//no newline
printf("\x1B[31mError\x1B[0m: too long.\n%s",prompt);
size = strlen ( temp);
do {
fgets ( temp, sizeof temp, stdin);//read more and discard
size += strlen ( temp);
} while (!strchr ( temp, '\n'));//loop until newline found
printf("size :%i\n",size);
continue;//re prompt
}
break;
}
else {
fprintf ( stderr, "fgets problem\n");
return NULL;
}
}
temp[strcspn ( temp,"\n")] = '\0';//remove newline
string word = malloc(strlen ( temp) + 1);
strcpy ( word, temp);
return word;
}
这是同一个老错误一遍又一遍 C中的字符串以null结尾。这意味着保存字符串的内存必须大于字符串的长度
您检查读取的字符串长度是否不超过24个字符,但是在malloc中,您没有为空字符添加空间。因此,
strcpy
将空字符放在指定内存之外。如果您正在进行CS50练习,请将其添加为标记。否则人们会开始询问字符串的类型是什么(它不是标准类型,由CS50头文件定义)。我在我的库中定义了字符串,当我使用stripc时,换行符将被删除,缺少一个字符,因此大小正好是容纳空字符的尺寸,我不需要输入大小+1。temp[30]代码>->温度[30+1]
。同样,必须为空终止符预留malloc空间。还有一个bug导致了另一个bug,投票决定关闭这个bug。一旦答案开始出现,不要改变代码的性质——它会成为一个移动的目标。如果真的需要,可以追加。Post回滚。@chux是的,我会解决这个问题。谢谢它能工作,但我想知道如果我按自己的方式执行,获取输入的函数不能激活的原因。。。您能解释一下吗?之所以会发生这种情况,是因为第一次在stdin中写入的\n,但由于限制而没有在我的字符串中结束,这会干扰下一次读取,对吗?应该fgets(temp,sizeof temp,stdin)
使用temp[]
返回NULL
。对于这段代码,可能是一个无限循环。空终止与这个问题无关,我在代码中加入了+1,但它并没有改变一个事实,即应该读取短语的函数在循环的第二次迭代中没有激活。我知道什么是空终止