C语言 为什么gets()不使用整行输入?

dojqjjoe  于 2022-12-03  发布在  其他
关注(0)|答案(7)|浏览(125)

我试图使用gets()从用户那里获取字符串,但是程序似乎直接跳过了gets()。没有暂停给予输入。为什么gets()什么也不做?

char name[13];
printf("Profile name: ");
gets(name);
printf("\n%s", name);
wqlqzqxt

wqlqzqxt1#

在调用gets()或fgets()之前调用getchar()。由于gets()或fgets()被跳过是因为stdin中先前的输入中已经存在“\n”,调用getchar()将导致其本身被跳过,而不是gets()或fgets()或任何其他类似的函数。但请记住,这更多的是一种黑客行为,而不是一种标准的解决方案(我认为是这样),并且禁止使用gets()。

printf("\nEnter a String: ");
        getchar();
        //fgets(inputString, 100, stdin);
        gets(inputString);
        printf("\n%s", inputString);
jbose2ul

jbose2ul2#

因为gets()使用起来非常危险,所以一些C库已经完全删除了它,并用一个什么都不做的版本来代替它。
请改用fgets()

oewdyzsn

oewdyzsn3#

使用flush(标准输入);在gets()之前

xpszyzbs

xpszyzbs4#

使用gets()会遇到很多问题
而不是选择fgets()

fgets(name,13,stdin);

请参阅此SO问题Why is the gets function so dangerous that it should not be used?
fgets()不起作用的原因可能是您没有处理scanf在前面的语句中留下的换行符。
您可以修改scanf格式字符串以将其考虑在内:scanf("%d *[^\n]", &N);
*[^\n]表示忽略整数输入之后的所有非换行符的内容,但不要对换行符做任何操作(跳过它)。
当您使用scanf("%d",&num)时,会遇到13和enter13存储在num中,并且newline字符仍在输入缓冲区中。当您从stdin读取fgets时,它会将\n视为您已输入的数据,并跳过fgets()语句
您不能刷新输入缓冲区,但可以执行此操作fseek(stdin,0,SEEK_END);在每个fgets语句之前添加此内容

q35jwt9p

q35jwt9p5#

看一看gets() reference

从标准输入获取字符串

从标准输入(stdin)读取字符,并将其作为C字符串存储到str中,直到到达换行符或文件结尾。
如果找到换行符,则不将其复制到字符串中。
在复制到字符串的字符之后自动追加终止空字符。
请注意,gets与fgets有很大的不同:gets不仅使用stdin作为源代码,而且在结果字符串中不包含结束换行符,也不允许指定str的最大大小(这可能导致缓冲区溢出)。
因此,基本上gets()不仅不安全(可能导致缓冲区溢出),而且还读取输入缓冲区中的内容。
我建议您使用fgets(),但是如果您想要一个快速(* 和懒惰和愚蠢 *)的解决方案,只需刷新输入缓冲区:

char name[13];
printf("Profile name: ");
fflush(stdin);
gets(name);
printf("\n%s", name);
btxsgosb

btxsgosb6#

将下面的函数添加到您的代码中,并享受它。

string GetString()
{
   char ch;
   string Line="";

   while(1)
   {
       ch=getchar();

       if(ch=='\n')
          break;
       else
          Line+=ch;
    }

    return Line;
}

这个功能可以影响所有空格和退格键!!!

elcex8rz

elcex8rz7#

您可能需要丢弃该行的其余部分,并移到下一行的开头。您可以执行以下操作:

int c; while((c=getchar()) != '\n' && c != EOF);

这将丢弃当前行的其余部分(可能已使用scanf()等部分读取),并移到下一行。
尽管fflush(stdin)也可能丢弃输入,但这是非标准行为,不鼓励这样做。
永远不要使用gets(myString),因为它不安全,已经从C标准中完全删除了。它不强制字符串的尺子,因此您可以越过缓冲区的末尾并覆盖RAM中的其他值,从而导致缓冲区溢出,这可能是一个安全漏洞。使用fgets(myString, myStringSize, stdin);若要去掉结果字符串中的换行符,请使用myString[strcspn(myString, "\n")] = 0;

相关问题