简体   繁体   English

如何在我的 C 程序中多次使用“获取”function?

[英]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 个字符ab ,能够容纳.

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循环中ab的定义没有任何意义,即使很难,这只是一个玩具程序,用于学习目的。

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM