关于scanf()和空白的问题

2exbekwf  于 5个月前  发布在  其他
关注(0)|答案(2)|浏览(39)

我是一个C新手,(刚开始学习它),所以请不要太注意我的无知。
现在的问题。它涉及到scanf()[^\n]的使用(以我的学习书为例)。然而,它似乎根本不起作用。
先谢谢你了。
下面的代码片段在编译时什么也不打印(如果用户输入了一个带空格的字符串),为什么?

#include <stdio.h>

int main(void) {

    char str[100];

    printf("Enter a string: ");
    scanf("%[˄\n]", str);
    printf("%s\n", str);
  
    return 0;
}

字符串
因此,例如,如果用户输入This is a text,它什么也不输出!另一方面,如果没有[^\n],它会打印字符串直到第一个空白。

omjgkv6w

omjgkv6w1#

您在格式字符串中键入的字符不是ASCII插入符号,它是一个以UTF-8编码为2个字节的Unicode扬抑符重音˄ U+02 C4 [CB 84]。因此格式字符串是%[\xCB\x84\n],因此scanf()只接受这3个字节的任意组合的序列。
如果用户输入其他字符作为第一个字符,scanf()将在用户按下Enter键后返回0。相反,如果用户按下Enter键,\n将被接受并继续输入,直到输入不同于3个字节的字符,但只有当用户再次按下Enter键时,该字符才可用。
观察到的行为是,只要输入Enter键,输入就会继续,然后输出多个换行符,str中的换行符后面跟着最后一个换行符。
您可能在键盘上键入了扬抑符重音(可能是法语AZERTY或类似的布局),后跟一个空格,而不是AltGr 9组合键。
%[^\n]还有其他问题:

  • scanf()没有办法找到目标数组的长度,任何足够长的输入都会导致缓冲区溢出。2你应该写%99[^\n]
  • 如果用户通过按Enter键输入一个空行,scanf()将返回0,使缓冲区str保持不变,因此未初始化。
  • 如果输入流为空,则scanf()将返回EOF,也不修改缓冲区str
  • 由用户输入的换行符在输入流中保持待决,潜在地导致使用scanf()fgets()的后续输入的混乱行为。

因此,您应该始终测试scanf()的返回值,以检测和报告无效或丢失的输入,而不是调用未定义的行为,并且使用fgets()从用户读取字符串不会那么令人困惑。
以下是修改后的版本:

#include <stdio.h>

int main(void) {

    char str[100];

    printf("Enter a string: ");
    if (scanf("%99[^\n]", str) == 1) {
        printf("%s\n", str);
    } else {
        printf("invalid or missing input\n");
    }
    return 0;
}

字符串
以下是使用fgets()从用户输入字符串的推荐方法:

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

int main(void) {

    char str[101];

    printf("Enter a string: ");
    if (fgets(str, sizeof str, stdin)) {
        str[strcspn(str, "\n")] = '\0';  // strip the trailing newline if any
        printf("%s\n", str);
    } else {
        printf("cannot read from input\n");
    }
    return 0;
}

flvtvl50

flvtvl502#

您使用了错误的符号˄。正确的符号是ASCII字符集中的一个:^。这通常发生在某些东西(例如互联网网站或键盘)对代码应用自动更正时,认为它是文本。
有些编译器在看到代码中的可疑字符时会发出警告。请注意这些警告!不幸的是,有些编译器只是说“你的代码中有一个错误的字符”,而没有说是哪个字符以及在哪里。

相关问题