c语言字符统计问题getchar,关于io:了解C中字符计数程序中的getchar()

这是我上一个问题的后续问题。已经提出了类似的问题(问题)。但我从那个答案中得不到我想知道的东西。

从上一个问题我开始知道,如果我键入了很多字符,那么它们就不能用于getchar(),直到我按Enter键。因此,当我按Enter键时,所有字符都将可用于getchar()。现在考虑以下用于字符计数的程序:

#include

main()

{

long nc;

nc=0;

while(getchar()!=EOF)

++nc;

printf("    Number of chars are %ld",nc);

}

如果我按以下顺序从命令行输入字符:{1,2,3,^ Z,4,5,回车},则在下一行{^ Z,Enter}。我期望的输出是:Number of chars are 6。但我得到的输出是Number of chars are 4。

这个答案解释了当我们输入1,2,3,^Z时,^Z就像Enter一样,1,2,3被发送到getchar()s。上面编写的代码的while循环运行三次。 ^Z未赋予getchar(),因此程序尚未终止。我的输入是{1,2,3,^ Z,4,5,Enter}。在^ Z之后我按了4,5然后回车。现在,当我按Enter键4,5和Enter时,应该给getchar()s,while循环应该执行三次以上。然后在最后一行我输入{^ Z,Enter},因为^ Z后面没有文字,所以它被视为一个字符,当我按下Enter键时,这个^ Z作为getchar()和while的输入给出循环终止。在所有这些中,while循环执行了6次,因此变量nc应该变为6。

Why am I getting 4 as the value of nc, rather than 6.

你使用哪个平台?如果你正在使用Linux,你可能想按^ D而不是^ Z.

@Marian我正在使用Windows-7。

@Marian您是stackoverflow.com/a/27184020/3429430的作者!你可以解释一下我的问题。

Windows与Linux不同,Windows ^ Z不等同于Linux ^ D.可能Windows操作系统会将^ Z转发给程序,然后切断其余的输入。

如果我输入{1,2,3,^ Z,4,5,Enter},则输入{1,2,3,^ Z,4,5,Enter},然后输入{^ Z,Enter}。输出为nc = 8。表示不切断Enter后的输入。

据我所知,DOS / Windows上的^ Z是"文件结束"标记,并被解释为"超出此点没有进一步输入"。所以^ Z本身被计算在内但没有超出它。当您自己打开文件时,您可以通过将"b"修饰符添加到fopen()(对于b inary输入)来禁用此功能,但标准输入流没有应用此修饰符。

^ Z仅在其后面没有文本时计算。如果^ Z被计算,那么当我输入1,2,3,^ Z,4,5,Enter}时程序应该最终终止。但该程序将文本的下一行作为进一步输入。

您必须指定main(或任何其他功能)的类型。

^ Z不在行的??开头不终止输入,它只终止当前行。

@牛米。我为什么要指定main()的类型?

因为C语言标准是这样说的。

添加一些输出将帮助您:

#include

int

main (void)

{

int c, nc = 0;

while ((c = getchar ()) != EOF)

{

++nc;

printf ("Character read: %02x

", (unsigned) c);

}

printf ("Number of chars: %d

", nc);

}

Windows控制台将^Z输入视为"在^Z之前发送输入到stdin,丢弃该行上的剩余输入(包括行尾分隔符),并发送^Z",除非它位于开头的 一行,在这种情况下,它发送EOF而不是^Z:

123^Z45

Character read: 31

Character read: 32

Character read: 33

Character read: 1a

^Z12345

Number of chars: 4

此外,Windows始终等待Enter / Return键,但或^{Break}等极少数键序列除外。

123 ^ Z45给我字符读取:31字符读取:32字符读取:33字符读取:1a(而不是1b)。是不是^Z -1的值?

@ user31782 1a,我编辑了答案以反映出来。 ^A具有01的十六进制代码,^B具有02的十六进制代码等,意味着^Z是1a。在Windows上EOF是-1,当您在行的开头键入^Z时,它会发送EOF而不是十六进制代码1a,这可能是您认为^Z是-1的原因。

什么是^Z的ASCII值?编译器采用不同的方式吗?

^Z的ascii值为26(十六进制为1a)。因此,当^ Z位于一行的开头时,它的值为-1,否则为ACSII值1a。

@ user31782是的,这是正确的。一行开头的^Z使getchar返回EOF( - 1)。否则getchar返回^Z的ASCII值。

^ Z或Ctrl-Z表示文本文件(旧MS-DOS)的文件结尾。 getchar()等效于fgetc(stdin),通常是一个宏。"fgetc返回读取为int的字符或返回EOF以指示错误或文件结尾。"

另请参阅_set_fmode,但是,我不确定是否会立即更改行为或是否必须关闭/重新打开文件。 不确定是否可以关闭/重新打开stdin(不再进行太多的控制台编程)。

你可以改写这个语句[所以输入库看到文件结束,然后将读取的缓冲区转发给程序。]。我不是母语人士。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值