[英]How can I use the “gets” function many times in my C program?
我的代码:
#include <stdio.h>
#include <math.h>
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
char a[10],b[10];
puts("enter");
gets(a);
puts("enter");
gets(b);
puts("enter");
puts(a);
puts(b);
}
return 0;
}
Output:
1
enter
enter
surya (string entered by user)
enter
surya (last puts function worked)
对您来说最重要的信息是:
永远不要使用gets
它不能防止缓冲区溢出。 您的缓冲区可以容纳 9 个字符和终止字符,但 get 将允许用户输入更多字符,从而覆盖程序gets
的其他部分。 攻击者可以利用它。 所以没有gets
任何程序。
改用fgets
!
这就是说 - 你出了什么问题?
scanf
在输入 stream 中留下一个换行符(又名'\n'
)。 所以第一个gets
只是读取一个空字符串。 第二个gets
然后读取“surya”。
像这样测试它:
#include <stdio.h>
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
char a[10],b[10];
puts("enter");
gets(a); // !!! Use fgets instead
puts("enter");
gets(b); // !!! Use fgets instead
puts("enter");
printf("|%s| %zu", a, strlen(a));
printf("|%s| %zu", b, strlen(b));
}
return 0;
}
输入:
1
surya
whatever
Output:
enter
enter
enter
|| 0|surya| 5
所以在这里你看到a
只是一个空字符串(长度为零),而b
包含单词“surya”(长度为 5)。
如果您使用fgets
,您可以保护自己免受用户启动的缓冲区溢出 - 这很重要。
但是fgets
不会删除scanf
中剩余的'\n'
。 你仍然必须摆脱你自己。
为此,我建议也删除scanf
。 使用fgets
后跟sscanf
。 喜欢:
if (fgets(a,sizeof a, stdin) == NULL)
{
// Error
exit(1);
}
if (sscanf(a, "%d", &t) != 1)
{
// Error
exit(1);
}
因此,当输入tin t
时,上面的代码将自动从输入stream 中删除'\n'
,随后的fgets
将从下一个单词开始。
把它们放在一起:
#include <stdio.h>
int main()
{
int t;
char a[10],b[10];
if (fgets(a,sizeof a, stdin) == NULL)
{
// Error
exit(1);
}
if (sscanf(a, "%d", &t) != 1)
{
// Error
exit(1);
}
while(t--)
{
puts("enter");
if (fgets(a,sizeof a, stdin) == NULL)
{
// Error
exit(1);
}
puts("enter");
if (fgets(b,sizeof b, stdin) == NULL)
{
// Error
exit(1);
}
puts("enter");
printf("%s", a);
printf("%s", b);
}
return 0;
}
输入:
1
surya
whatever
Output:
enter
enter
enter
surya
whatever
最后说明:
fgets
将 - 与gets
不同 - 还将'\n'
保存到目标缓冲区中。 根据您要执行的操作,您可能必须从缓冲区中删除该'\n'
。
如何在 C 程序中多次使用“gets” function?
你永远不应该在你的程序中使用gets()
。 它已被弃用,因为它可能会导致缓冲区溢出,因为它不可能停止消耗特定数量的字符 - fe 并且最重要的是 - 缓冲区的字符数量,每 10 个字符a
或b
,能够容纳.
这里也解释了:
为什么 get function 如此危险以至于不应该使用?
特别是,在乔纳森莱弗勒的这个回答中。
请改用fgets()
。
此外, while
循环中a
和b
的定义没有任何意义,即使很难,这只是一个玩具程序,用于学习目的。
此外请注意,该scanf()
留下换行符,由按下从stdin
中的scanf()
调用返回。 你必须抓住这个,否则之后的第一个fgets()
将消耗这个字符。
这是更正后的程序:
#include <stdio.h>
int main()
{
int t;
char a[10],b[10];
if(scanf("%d",&t) != 1)
{
printf("Error at scanning!");
return 1;
}
getchar(); // For catching the left newline from scanf().
while(t--)
{
puts("Enter string A: ");
fgets(a,sizeof a, stdin);
puts("Enter string B: ");
fgets(b,sizeof b, stdin);
printf("\n");
puts(a);
puts(b);
printf("\n\n");
}
return 0;
}
执行:
$PATH/a.out
2
Enter string A:
hello
Enter string B:
world
hello
world
Enter string A:
apple
Enter string B:
banana
apple
banana
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.