“获取;”之间的区别 和“scanf(”%s”, s);” 在C中

Ngu*_*Hậu 1 c string gets scanf

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

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;
}
Run Code Online (Sandbox Code Playgroud)

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

chu*_*ica 6

允许用户输入五个名称

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

代码还存在许多其他问题。


“获取;”之间的区别 和“scanf(”%s”, s);” 在C中

一个读一行,另一个读一个

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

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

  • 过时的gets()将读取并保存行输入到并包括'\n'. 已'\n'读取,但未保存。如果之前的输入操作留下了 a '\n'in stdin,则gets()读取一小行"\n"并另存为"".

  • scanf("%s", s)读取并丢弃任意数量的前导空白字符(可能是多个'\n'),然后读取并保存非空白字符。接下来的空格会停止读取,但会返回到stdin下一个输入函数。

  • 对于公共输入,scanf("%s", s)通常会将最后一个'\n'输入留给stdin下一个输入操作。 gets()消耗它。

  • 如果发生任何读取,两者都会附加一个空字符s

  • gets()返回一个指针。 scanf()返回转换计数。

建议

  • 不要在生产代码中使用gets(s)或。scanf("%s", s)阅读一行,研究fgets()。要读取单词,请使用类似 的宽度char s[100]; scanf("%99s", s);进行研究。

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

  • 在您明白为什么这样做不好之前,不要fgets()/gets()与函数混合使用。scanf()


其他

  • if(strcmp(s[j], s[j-1]) == -1)很穷。 strcmp()返回一些负数、零或一些正数来指示顺序。更好用if(strcmp(s[j], s[j-1]) < 0)

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