【问题标题】:Why the behaviour differs when fgets() is used instead gets()为什么使用 fgets() 而不是 gets() 时行为会有所不同
【发布时间】:2015-08-23 20:04:10
【问题描述】:

根据gcc警告:

`gets' 功能很危险,不应使用

我尝试使用fgets(),但它并没有在我的代码中出现,因为您可能会在下面的代码末尾看到两者的输出。有人可以告诉我我在做什么错误(如果有的话)吗?

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

#define size 128

int Table[size];

/****ShiftTable Function Declaration****/
void ShiftTable(char Pattern[]);

/****Horspool Function Declaration****/
int Horspool(char Pattern[],char Text[]);

/****Main Function****/
int main()
   {
    char Text[100],Pattern[100];
    int pos;

    printf("Enter the Text : ");
    gets(Text);                    //Works fine
    //fgets(Text,100,stdin);       //Does not work

    printf("\nEnter the Pattern: ");
    gets(Pattern);                 //Works fine
    //fgets(Pattern,100,stdin);    //Does not Work

    pos=Horspool(Pattern,Text);

    if(pos==-1)
            printf("\nPattern Not Found!\n\n");
    else
        printf("\nPattern Found at %d position.\n\n",pos+1);        

    return 0;
   }

/****Horspool Function Definition****/
int Horspool(char Pattern[],char Text[])
   {
    int m,n,i,k;

    n=strlen(Text);
    m=strlen(Pattern);

    ShiftTable(Pattern);

    i=m-1;

    while(i<n)
         {
        k=0;
        while(k<m && (Text[i-k]==Pattern[m-1-k]))  k++;

        if(k==m)   return i-m+1;

        i+=Table[Text[i]];
         }

    return -1;
    }

/****ShifTable Function Definition****/
void ShiftTable(char Pattern[])
    {
    int i,m;
    m=strlen(Pattern);

    for(i=0;i<size;i++)
        Table[i]=m;

    for(i=0;i<m-1;i++)
        Table[Pattern[i]]=m-1-i;
    }

输出:

当我使用gets()

majid@majid-K53SC:~ $ ./a.out

输入文本:班加罗尔是花园城市

输入图案:GARDEN

在第 14 个位置找到模式。

当我使用fgets()

majid@majid-K53SC:~ $ ./a.out

输入文本:班加罗尔是花园城市

输入图案:GARDEN

找不到模式!

【问题讨论】:

    标签: c fgets gets


    【解决方案1】:

    fgets 使用换行符(输入字符串后按 Enter )并将其存储在 Text 中,而 gets 不使用。您需要从Text 转至strip the newline character off

    所以,在两次调用 gets 之后,

    Text = "BANGALORE IS GARDEN CITY"
    Pattern = "GARDEN"
    

    对于fgets

    Text = "BANGALORE IS GARDEN CITY\n"
    Pattern = "GARDEN\n"
    

    【讨论】:

    • 感谢您的回答和链接
    • 我尝试了链接中给出的两种方法,但都没有成功,我不知道是什么问题......我厌倦了 fgets() !请告诉我出了什么问题:要么 strtok(Pattern,"\n");或 ln = strlen(模式);模式[ln] = '\0';让它进入无限循环!
    • @MajidNK,使用size_t ln = strlen(Pattern); if(ln != 0) Pattern[ln-1] = '\0';。如果你愿意,你可以对Text 做同样的事情
    • 你在哪里使用它?在第二个 fgets 之后使用它。
    • 知道了 :) 这是大小的问题 //size 必须至少为 128 才能包含键盘中所有键的 asci 码……它是 100,所以大写字母没有问题,但是当小写输入它已经进入无限循环
    【解决方案2】:

    首先,感谢您注意警告。你切换到fegts()是非常正确的。

    现在,回答你的问题,

    为什么当使用 fgets() 而不是 gets() 时行为会有所不同?

    这不是一个奇怪的行为。这是fgets() 的预期行为。

    gets() 不同,fgets() 读取并存储尾随 newline 到提供的输入缓冲区中。在进行比较之前,您需要去掉换行符。

    没有它,基本上,你的输入看起来像:

    Text    --> "BANGALORE IS GARDEN CITY\n"
    Pattern --> "GARDEN\n"
    

    现在,正如我们所知,"GARDEN ""GARDEN\n"相同,因此您的比较失败了。

    也就是说,只是一个建议,main() 的推荐签名是int main(void)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-05-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-12
      • 1970-01-01
      • 2023-03-15
      相关资源
      最近更新 更多