我是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],它会将字符串打印到第一个空格.

推荐答案

您在格式字符串中键入的字符不是ASCII脱字符符号,它是以UTF-8编码为2字节[CB 84]的Unicode舍音符˄ U+02C4.因此,格式字符串是%[\xCB\x84\n],因此scanf()只接受这3个字节的任意组合的序列.

如果用户输入其他字符作为第一个字符,则在用户按Enter键后,scanf()将返回0.相反,如果用户按Enter键,则接受\n并继续输入,直到输入不同于3个字节的字符,但只有当用户再次按Enter键时才能使用.

观察到的行为是,只要只键入Enter键,输入就会继续,然后输出多个换行符,其中str行后面跟着最后一个换行符.

您可能在键盘上键入了抑扬符(可能是法语AZERTY或类似布局),后跟一个空格,而不是AltGr9组合键.

%[^\n]格式还有其他问题:

  • scanf()无法找到目标数组的长度,任何足够长的输入都会导致缓冲区溢出.你应该写%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;
}

C++相关问答推荐

如何在C中通过转换为char * 来访问float的字节表示?

C中的ATONE会扰乱SEN/CLUTE GMS应用程序中的其他字符串

使用SWI—Prolog的qsave_program生成二进制文件有什么好处?'

__VA_OPT__(,)是否可以检测后面没有任何内容的尾随逗号?

如何知道我是否从非阻塞套接字读取所有内容

GCC不顾-fno-Builtin-SINCOS旗帜向SINCOS发出呼唤

从uint8_t*转换为char*可接受

Printf()在C中打印终止字符之后的字符,我该如何解决这个问题?

如何在不使用字符串的情况下在c中编写函数atof().h>;

不带Malloc的链表

发送和接收的消息中的Unix域套接字不匹配

强制GCC始终加载常量(即只读),即使启用了优化

try 判断长整数是否为素数

如何不断地用C读取文件?

尽管将其标记为易失性,但 gcc 是否优化了我的等待代码?

添加/删除链表中的第一个元素

Makefile - 将 .o 文件放入子文件夹中

创建 makefile 来编译位于不同目录中的多个源文件

如何确保 gcc + libc 对于多字节字符串使用 UTF-8,对于 wchar_t 使用 UTF-32?

计算 e^x 很好.但不是 x 的罪