【问题标题】:Why does getchar let single-character output functions display strings?为什么getchar让单字符输出函数显示字符串?
【发布时间】:2015-09-16 04:52:46
【问题描述】:

刚开始使用 K&R 并点击:

#include <stdio.h>
/* copy input to output; 1st version */
main()
{
    int c;
    c = getchar();
    while (c != EOF) {
        putchar(c);
        c = getchar();
    }
}

它只显示我输入的内容,即使它是一串文本。

cacti
cacti
stop repeating what i'm saying
stop repeating what i'm saying

就这样。

我不明白为什么我不能用一串文本实例化变量 c 并以相同的方式打印它。 (为了示例而忽略 while 循环)就像:

main()
{
    int c;

    c = "cacti";
    putchar(c);
}

其中的输出显然只是 'd'

【问题讨论】:

  • 每个getchar 读取一个字符,每个putchar 显示一个字符。 cacti。整个单词永远不会一次存储。您不会立即看到每个字符都回显,因为您的输入是按行缓冲的。 d"cacti" 指针的最后一个字节在解释为文本时的最终结果。
  • 在哪个操作系统上? C不知道键盘!见this & that
  • @minitech 哦。这实际上很有意义。凯谢谢! ..啊。我谋杀了这个问题:c

标签: c character getchar


【解决方案1】:

这里 c 是唯一的整数,它为你的情况取一个字符(尽管它的限制大于那个)。

对于第一个代码段:

  • getchar() 只返回一个字符,您使用 while 循环从流中获取一个字符并通过putchar() 它打印到控制台直到文件结束。你似乎得到了一行字符串并打印它,但它不是那样做的。

在第二个代码段中:

  • 您将 const char* 放入无效的整数(我的 gcc 4.9.2 无法编译)。所以它显示未定义的字符(为什么打印'd'我不知道,可能是编译器问题)。

您可以这样做:

main()
{
    char c[] = "cacti";
    puts(c);
}

编辑 根据getchar()定义:

成功时,返回读取的字符(提升为 int 值)。 返回类型为 int 以适应特殊值 EOF,表示失败。

当您键入一行并按 enter 时,第一个字符会在 while 循环之外读取。比检查它是否是 EOF(文件结束 - 文件上没有更多数据。您可以通过在 Windows 中按 Ctrl+Z 和在 linux 中按 Ctrl+D 来提供 EOF)。

如果没有遇到EOF,则进入while循环并打印单个字符(putchar(c))。在下一行c=getchar() 之后,取您在上一行输入的另一个字符并检查while 循环条件while(c!=EOF) 是否为真,它进入循环并打印一个字符。它一直持续到找到要打印的任何字符为止。

因此它与在标准输出中写入字符串的puts() 混淆。 其中putchar() 将一个字符写入标准输出。

根据http://www.cplusplus.com/

将 str 指向的 C 字符串写入标准输出 (stdout) 并附加换行符 ('\n')。

【讨论】:

  • 请注意,您通常使用黄色的“引用”符号来引用别人的作品。看来您正在使用它来表达自己的措辞。虽然不是绝对错误,但它有点不正统。粗略地讲,如果您没有要引用的外部引用(最好带有 URL),您可能不应该使用 &gt;-at-start-of-line 引用机制。
  • 感谢@JonathanLeffler。下次我会小心的。
【解决方案2】:

您可以使用面向行的输入函数来读取整行。例如:

#include <stdio.h>

int main(void)
{
    char line[4096];
    while (fgets(line, sizeof(line), stdin) != 0)
        fputs(line, stdout);
    return 0;
}

对于大多数看似合理的文件,这将一次将一行读入字符数组,然后将该行写出。 (如果行长超过 4095 个字符,则行将分多段处理。)如果文件包含空字节,则从空字节到行尾的材料将被忽略。对此有修复 - 请参阅标准 C 函数 fread()fwrite(),以及 POSIX 函数 getline().


请注意您的第二个示例:

int main(void)
{
    int c;

    c = "cacti";
    putchar(c);
}

如果没有关于将字符指针分配给整数的警告,则不应编译。当您在结果上使用putchar() 时,它可能会打印存储字符串"cacti" 的地址的最低有效字节。打印的字符是d纯属巧合。

putchar() 函数只打印一个字节(这意味着在许多代码集中的单个字符,但它可能只是 UTF-8 中字符的一部分)。

【讨论】:

    猜你喜欢
    • 2021-12-03
    • 1970-01-01
    • 2015-01-13
    • 1970-01-01
    • 2020-01-10
    • 1970-01-01
    • 1970-01-01
    • 2012-07-29
    相关资源
    最近更新 更多