簡體   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