"gets(s);" 和 "scanf("%s 之间的区别", s);"在 C

Difference between "gets(s);" and "scanf("%s", s);" in C

我正在编写一个程序,允许用户输入五个名字并按字母顺序对这些名字进行排序,两个相邻的名字用换行符分隔。这是我的代码:

void sortWords(char s[][100], int n){
    int i, j;
    char *str;
    for(i = 0; i < n-1; i++){
        for(j = n- 1; j > i; j--){
            if(strcmp(s[j], s[j-1]) == -1){
                strcpy(str, s[j]);
                strcpy(s[j], s[j-1]);
                strcpy(s[j-1], str);
            }
        }
    }
}
int main(){
    char s[5][100];
    int i;
    for(i = 0; i < 5; i++){
        fflush(stdin);
        //gets(s[i]);      // when I use this statement, my program doesn't work
        scanf("%s", s[i]);
    }
    sortWords(s, 5);
    for(i = 0; i < 5; i++){
        printf("%s ", s[i]);
    }
    return 0;
}

当我将主函数中的“scanf”更改为“gets”时,输入了 5 个名称后,程序没有打印任何内容。任何人都可以为我解释一下,因为通常情况下,当我将其中一个更改为另一个功能时,我只会得到相同的结果。

allows users to enter five names

名字的全名部分之间通常有一个 space。 scanf("%s", s) 不读全名,只读部分名字。

代码也有很多其他问题。


Difference between "gets(s);" and "scanf("%s", s);" in C

一个读另一个读

  • gets(),因为 C11 (2011) 不再是 C 标准库的一部分。

  • 两者都不好,因为它们不限制输入,因此可能会发生缓冲区溢出。

  • 过时的 gets() 将读取并保存 - 输入并包含 '\n''\n' 已读取,但未保存。如果之前的输入操作在stdin中留下了一个'\n',那么gets()读取了一小段"\n"并保存为"".

  • scanf("%s", s) 读取并丢弃任意数量的前导 white-space 字符(可能是多个 '\n'),然后读取并保存非 white-space 字符.后面的 white-space 停止读取,但它被 return 编辑为 stdin 用于下一个输入函数。

  • 对于普通输入,scanf("%s", s)通常会在stdin中留下最后的'\n'进行下一次输入操作。 gets() 消耗它。

  • 两者都会在 s 后附加一个 空字符 (如果有任何读数)。

  • gets() return是一个指针。 scanf() return 转换计数。

建议

  • 不要在生产代码中使用 gets(s)scanf("%s", s)。要阅读 ,请研究 fgets()。要阅读单词,请使用 width 进行研究,例如 char s[100]; scanf("%99s", s);.

  • 最好测试I/O函数的return值。

  • 不要将 fgets()/gets()scanf() 函数混合使用,直到您理解为什么这样不好。


其他

  • if(strcmp(s[j], s[j-1]) == -1)很穷。 strcmp() return 一些负数、零或一些正数来表示顺序。最好使用 if(strcmp(s[j], s[j-1]) < 0).

  • strcpy(str, s[j]); 不好,因为指针 str 尚未赋值。更好的 char str[100]; strcpy(str, s[j]);.

gets() 读取 scanf("%s") 读取 单词 ,两者都不应该使用。

有关详细信息,请阅读@chuxReinstateMonica 的