无法使用 scanf 读取任何字符

Can't read in any characters with scanf

提问人:Yanic Hermann 提问时间:10/16/2023 最后编辑:John KugelmanYanic Hermann 更新时间:10/16/2023 访问量:114

问:

我编写了一个程序,它读取整数、浮点数和字符并输出格式化。但是,它并不完全有效,因为如果我启动程序,我将无法阅读任何字符。

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int main() {

    int a;
    float b;
    char c;

    scanf("%d", &a);
    scanf("%f", &b);
    scanf("%s", &c);

    printf("%-14s: %010d\n", "Ganzzahlen", a);
    printf("%-14s: %5.5f\n", "Gleitkommazahl", b);
    printf("%-14s: %c\n", "Zeichen", c);

    return 0;
}
c 扫描

评论

2赞 jarmod 10/16/2023
用于字符串和字符。%s%c
2赞 Fe2O3 10/16/2023
用于偶然的非空格“字符串”。使用(注意前导 SP)在预期的单个字符之前丢弃空格..."%s"" %c"
0赞 TheEagle 10/16/2023
用于单个字符和 s 数组(声明为 ),也称为字符串。%c%scharchar** s;
0赞 M.M 10/16/2023
@TheEagle读取的是字符串,而不是数组。与它一起使用是错误的.%schar **
0赞 chux - Reinstate Monica 10/16/2023
@Yanic Hermann,发布一个输入示例。

答:

1赞 Chris 10/16/2023 #1

如注释中所述,您希望为类型使用正确的格式说明符。对于单个字符,正确的说明符是 。%c

但是,这将读取任何字符,因此请使用前导空格,以便忽略字符前的前导空格。如果没有此内容,读取先前输入后的空间仍位于缓冲区中,并立即读取。" %c"scanf

您还应该养成检查返回值的习惯,以确保读入的值数量正确。scanf

0赞 arfneto 10/16/2023 #2

scanf之所以这样命名,是因为它是一个扫描器。它不是为了使用来自键盘的数据而编写的,这是一个自由格式的输入。 编写时会使用表格数据,例如巨型文件。 在这些文件中,每一行都称为一条记录,并包含由分隔符分隔的字段,标准字段为逗号。 代表逗号分隔值。例如,这里用作分隔符。 设置 的用法。scanfcsvcsv"%d %f %2s"space"%d:%f:%2s:

  • scanf根据说明符跳过空格,例如空格制表符---和换行符。
  • scanf一旦满足说明符或行结束,就会停止。
  • 什么都不读是正常的。无论如何,它都是扫描仪。因此,返回一个包含读取值总数的值,或者在出现错误时返回一个负值。scanfint
  • 您需要使用结束每次调用的“\n”,否则它将干扰代码中的下一个调用scanfscanf
  • 调用清除缓冲区printfstdin
  • 读取单个字符是有问题的,因为无论如何都是缓冲的stdio
  • 考虑使用 to 消耗每行,然后将行馈送到 。通常,以这种方式控制键盘输入更容易fgets()sscanf()
  • 如果一次读取一个字段,则可以使用 OR 转换它们,并完全跳过这些扫描仪的使用:无论如何,它们都不是为此用途(键盘输入)而编写的。使用的好处是,您可以读取一行带分隔符的输入,并在一次调用中将所有字段转换为混合类型。atoi()atod()scanf()

示例的输出

   Please enter an integer: 42
   1 value(s) read: Ganzzahlen    : 0000000042
   Please enter a float number: 42.42
   1 value(s) read: Gleitkommazahl: 42.42000
   Please enter a char: one call
   1 value(s) read: Zeichen       : o 

法典

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main(void)
{
    int   a;
    float b;
    char  c[80];
    int   res = 0;

    printf("\n    Please enter an integer: ");
    res = scanf("%i", &a);
    printf("    %d value(s) read: ", res);
    if (res == 1) printf("%-14s: %010d\n", "Ganzzahlen", a);

    printf("    Please enter a float number: ");
    res = scanf("%f", &b);
    printf("    %d value(s) read: ", res);
    if (res == 1) printf("%-14s: %5.5f\n", "Gleitkommazahl", b);

    printf("    Please enter a char: ");
    res = scanf("%2s", &c);
    printf("    %d value(s) read: ", res);
    if (res == 1) printf("%-14s: %c\n", "Zeichen", c[0]);
    return 0;
}

评论

1赞 M.M 10/16/2023
scanf("%s, &c)应该是scanf("%19s", c)
0赞 arfneto 10/16/2023
暂时删除了 One Call/3 Values 输入。我没有时间更改和编辑答案来解释 oher 函数的使用,例如或 /calls。希望它仍然可以以这种方式减少有用。也许明天我会添加一个新例子FlushConsoleInputBuffer()fgets()sscanf
0赞 arfneto 10/16/2023
@Fe203 :)真?这从来都不是真的。借助 BI 和 AI,现在甚至可以向公众提供巨型数据源。在全球范围内,尝试 Data WorldKaggle。对于一个不那么全球化的人,请尝试使用超过一百万个 csv 可用数据集的四分之一 catalog.data.gov。这是我使用的最新产品:catalog.data.gov/dataset/crime-data-from-2020-to-present,有超过 800,000 行
0赞 arfneto 10/17/2023
尝试使用我引用的 800,000 行数据集。你可以有一个惊喜。scanf
0赞 arfneto 10/17/2023
@Fe203你发布的这句话是一个简单的玩具。在带引号的字段中插入 CSV 的分隔符没有任何意义。尝试浏览一些公共数据库,您将看到今天可用的内容。在“全局”或“本地”集中...csv 没有事实上的标准,因为它早于 Internet 以及 W3C 和 IETF。但是看看RFC4180,你可以学到一些东西