为什么getchar允许单字符输出函数显示字符串?

时间:2015-09-16 04:52:47

标签: c character getchar

刚开始使用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'

2 个答案:

答案 0 :(得分:5)

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

对于第一个代码段:

  • <?xml version="1.0" encoding="UTF-16"?> <instrumentationManifest xsi:schemaLocation="http://schemas.microsoft.com/win/2004/08/events eventman.xsd" xmlns="http://schemas.microsoft.com/win/2004/08/events" xmlns:win="http://manifests.microsoft.com/win/2004/08/windows/events" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:trace="http://schemas.microsoft.com/win/2004/08/events/trace"> <instrumentation> <events> <provider name="MyTrial2" guid="{90DDCC4A-2F8A-4B57-85AF-5401E678708A}" symbol="MyTrial2" resourceFileName="E:\MyEventTrial\MyEventTrial\Debug\MyEventTrial.exe" messageFileName="E:\MyEventTrial\MyEventTrial\Debug\MyEventTrial.exe"> <events> <event symbol="EvenEvent2" value="1" version="0" channel="TrialChannel2" level="win:Informational" message="$(string.MyTrial.event.1.message)"> </event> <event symbol="OddEvent2" value="2" version="0" channel="TrialChannel2" level="win:Informational" message="$(string.MyTrial.event.2.message)"> </event> <event symbol="ErrorEvent2" value="3" version="0" channel="TrialChannel2" level="win:Error" message="$(string.MyTrial.event.3.message)"> </event> </events> <levels> </levels> <channels> <channel name="TrialChannel2" chid="TrialChannel2" symbol="TrialChannel2" type="Admin" enabled="true"> </channel> </channels> </provider> </events> </instrumentation> </instrumentationManifest> 只返回一个字符并使用while循环从流中获取字符并通过getchar()将其打印到控制台直到文件结尾。你似乎得到了一行字符串并将其打印出来,但它并没有这样做。

在第二个代码段中:

  • 你把一个const char *放到了无效的整数(我的gcc 4.9.2不能编译)。因此它显示未定义的字符(为什么打印&#39; d&#39;我不知道,可能是编译器问题)。

您可以通过以下方式执行此操作:

putchar()

修改 根据{{​​3}}定义:

  

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

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

好像没有遇到EOF,然后它进入while循环并打印单个字符(main() { char c[] = "cacti"; puts(c); } )。在下一行putchar(c)之后,在前一行中输入另一个字符并检查while循环条件c=getchar()是否为真,它进入循环并打印一个字符。它一直持续到发现任何要打印的字符为止。

因此它与getchar()混淆,后者在标准输出中写入一个字符串。 其中while(c!=EOF)将字符写入标准输出。

根据puts()

  

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

答案 1 :(得分:1)

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

#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中字符的一部分)。