重定向标准输入

时间:2014-10-01 02:35:56

标签: c io stdin

我编译我的代码然后运行:$ ./a.exe< input.txt中 由于某种原因,它不会读取第一个字符(第一行测试中缺少t) 最后还有一个奇怪的角色。我该如何对抗这两个错误?  感谢

#include <stdio.h>
#include <stdlib.h>

int main(void) {    
    char c = getchar();    
    while (c != EOF){
        printf("%c ",c); 
        c = getchar();
    }
    return (0);
}        

示例执行:

$ ./a.exe < input.txt
  e s t   l i n e   o n e
 t e s t   l i n e   t w o
 f i n a l   l i n e ▒ 

3 个答案:

答案 0 :(得分:3)

首先,请注意,当您while首次执行时,c将被取消分配。

然后,请注意,当读取倒数第二个字符时,您的while测试将通过,导致读取并打印另一个字符 - 因此您将EOF的视觉表示视为最后一个字符

如果你正在将文件传送到这个程序中,我怀疑在你写的行之前有些东西会导致T被省略。

你可以通过以下方式避免其他问题:

    #include <stdio.h>
    #include <stdlib.h>

    int main(void) {    
        int c = getchar();    
        while (c != EOF){
            printf("%c ",c); 
            c = getchar();
        }
        return (0);
    }

编辑:我还建议我们在上面的评论中遵循user3125367的建议,这消除了从int到char的一些偷偷摸摸的转换。我上面编辑过使用int。这也可以让你使用%n来查看文件中第一个字符的实际值是什么,和/或它可以解决问题(即文件中的第一个字符可能看起来像T,但是值大于255的非ASCII字符。)

答案 1 :(得分:0)

我没有看到关于重定向stdin的任何重要信息。看起来你的文本文件有效地具有ASCII字符(是正确的 - 没有奇怪的符号?)。该文件可以编码为UTF-8(每个字符最多4个字节)或另一个多字节系统。对于UTF-8,保留ASCII字符的值,即全部小于128,因此可以将它们转换为带符号的字符而不会丢失精度。通常,UTF-8中的字符大小最多可达4个字节,因此至少需要存储int的大小。   你的代码有点尴尬,但我没有立即看到为什么它不应该工作,除非char类型是问题。但是,我尝试使用int和char并得到相同的结果(它工作正常)。这是我的代码(注释掉了char类型):

#include <stdio.h>
int main()
{//char c; // Wrong.  getchar returns int.
   int  c;
   while ( (c = getchar()) != EOF) printf("%c", c);
   return 0;
}

char c的输出相同;或int c;如下:

Test line 1
Test line 2
Last Line, no CR

编辑:交替的空格表示您的input.txt文件必须编码为UCS-2(双字节Unicode)或类似的东西;由于文本字符值均小于127,因此每隔一个字节为零。零作为空格打印,因为它们是“不可打印的”。我猜这里(没有时间检查出来)你的第一个输出线上的前导空间是由于两个字节的BOM(字节顺序标记),FF FE或FE FF,可能是无法打印。将输入文件保存为UTF-8或ANSI,然后重试。

答案 2 :(得分:-2)

不确定第一个错误是如何发生的,但这应该修复第二个错误:

int c;   
for (c = getchar(); c != EOF; c = getchar()) {
    printf("%c ",c);          
}

仔细检查以确保您的文件确实包含您缺少的第一个字符。

在使用int读取字符时使用getchar的原因是EOF常量是一个整数,not guaranteed表示有效的字符值。因此,当您将角色与EOF进行比较时,即使遇到EOF,与实际EOF常数相比也不会评估为真。

您还会注意到,您使用的这些功能(例如getcharputchar等)都会int而不是char(我知道,混淆正确) ?)。我认为这个决定主要是为了在不牺牲宝贵的字节的情况下增加对EOF的支持。