繁体   English   中英

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

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

这里也解释了:

为什么 get function 如此危险以至于不应该使用?

特别是,在乔纳森莱弗勒的这个回答中。

请改用fgets()


此外, while循环中ab的定义没有任何意义,即使很难,这只是一个玩具程序,用于学习目的。

此外请注意,该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.

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