[英]How can I use the “gets” function many times in my C program?
My code:我的代码:
#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: Output:
1
enter
enter
surya (string entered by user)
enter
surya (last puts function worked)
The most important message for you is:对您来说最重要的信息是:
Never use gets
- it can't protect against buffer overflow.永远不要使用gets
它不能防止缓冲区溢出。 Your buffer can hold 9 characters and the termination character but gets
will allow the user to typing in more characters and thereby overwrite other parts of the programs memory.您的缓冲区可以容纳 9 个字符和终止字符,但 get 将允许用户输入更多字符,从而覆盖程序gets
的其他部分。 Attackers can utilize that.攻击者可以利用它。 So no gets
in any program.所以没有gets
任何程序。
Use fgets
instead!改用fgets
!
That said - what goes wrong for you?这就是说 - 你出了什么问题?
The scanf
leaves a newline (aka a '\n'
) in the input stream. scanf
在输入 stream 中留下一个换行符(又名'\n'
)。 So the first gets
simply reads an empty string.所以第一个gets
只是读取一个空字符串。 And the second gets
then reads "surya".第二个gets
然后读取“surya”。
Test it like this:像这样测试它:
#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;
}
Input:输入:
1
surya
whatever
Output: Output:
enter
enter
enter
|| 0|surya| 5
So here you see that a
is just an empty string (length zero) and that b
contains the word "surya" (length 5).所以在这里你看到a
只是一个空字符串(长度为零),而b
包含单词“surya”(长度为 5)。
If you use fgets
you can protect yourself against user-initiated buffer overflow - and that is important.如果您使用fgets
,您可以保护自己免受用户启动的缓冲区溢出 - 这很重要。
But fgets
will not remove the '\n'
left over from the scanf
.但是fgets
不会删除scanf
中剩余的'\n'
。 You'll still have to get rid of that your self.你仍然必须摆脱你自己。
For that I recommend dropping scanf
as well.为此,我建议也删除scanf
。 Use fgets
followed by sscanf
.使用fgets
后跟sscanf
。 Like:喜欢:
if (fgets(a,sizeof a, stdin) == NULL)
{
// Error
exit(1);
}
if (sscanf(a, "%d", &t) != 1)
{
// Error
exit(1);
}
So the above code will automatically remove '\n'
from the input stream when inputtin t
and the subsequent fgets
will start with the next word.因此,当输入tin t
时,上面的代码将自动从输入stream 中删除'\n'
,随后的fgets
将从下一个单词开始。
Putting it all together:把它们放在一起:
#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;
}
Input:输入:
1
surya
whatever
Output: Output:
enter
enter
enter
surya
whatever
Final note:最后说明:
fgets
will - unlike gets
- also save the '\n'
into the destination buffer. fgets
将 - 与gets
不同 - 还将'\n'
保存到目标缓冲区中。 Depending on what you want to do, you may have to remove that '\n'
from the buffer.根据您要执行的操作,您可能必须从缓冲区中删除该'\n'
。
How can I use “gets” function many times in C program?如何在 C 程序中多次使用“gets” function?
You should never ever use gets()
in your program.你永远不应该在你的程序中使用gets()
。 It is deprecated because it is dangerous for causing buffer overflow as it has no possibility to stop consuming at a specific amount of characters - fe and mainly important - the amount of characters the buffer, a
or b
with each 10 characters, is capable to hold.它已被弃用,因为它可能会导致缓冲区溢出,因为它不可能停止消耗特定数量的字符 - fe 并且最重要的是 - 缓冲区的字符数量,每 10 个字符a
或b
,能够容纳.
Also explained here:这里也解释了:
Why is the gets function so dangerous that it should not be used? 为什么 get function 如此危险以至于不应该使用?
Specially, in this answer from Jonathan Leffler.特别是,在乔纳森莱弗勒的这个回答中。
Use fgets()
instead.请改用fgets()
。
Also the defintion of a
and b
inside of the while
loop doesn´t make any sense, even tough this is just a toy program and for learning purposes.此外, while
循环中a
和b
的定义没有任何意义,即使很难,这只是一个玩具程序,用于学习目的。
Furthermore note, that scanf()
leaves the newline character, made by the press to return from the scanf()
call in stdin
.此外请注意,该scanf()
留下换行符,由按下从stdin
中的scanf()
调用返回。 You have to catch this one, else the first fgets()
thereafter will consume this character.你必须抓住这个,否则之后的第一个fgets()
将消耗这个字符。
Here is the corrected program:这是更正后的程序:
#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;
}
Execution:执行:
$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.