每次从 stdin 读取 char 的最佳方法是什么?
What is the best way to read a char each time from stdin?
所以基本上我正在编写一个 C 程序,它从标准输入读取字节流并将字节视为 0 到 255 范围内的无符号整数。该程序计算 0 到 255 范围内的每个值出现的频率。它还接受一个非负整数作为命令行
争论。此命令行参数给出程序应生成的输出行数 n。因此,如果 n 为 16,程序应打印 16 行输出,显示 0 到 15 范围内的字节值出现的频率。
每行应以整数值开头,后跟计数,例如
0出现1014次
1 出现 1201 次
等等。
我尝试每次从标准输入读取一个字符并检查它是否为“\n”。然而,条件 (token != "\n") 永远不会 returns False 并且循环永远不会中断。
这是我的代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, const char* argv[]) {
char token;
int n;
if (argc != 2) {
printf("Error!\n");
exit(0);
}
n = atoi(argv[1]);
int i;
int freq[n];
for(i = 0; i<n; i++) {
freq[i] = 0;
}
int value;
printf(">");
token = fgetc(stdin);
while (token != "\n") {
printf("here!");
value = token;
if (value < n) {
freq[value] ++;
}
token = fgetc(stdin);
}
printf("there");
for(i = 0; i<n; i++) {
printf("%d occured %d times\n",i, freq[i]);
}
return 1;
}
您可以使用 getchar();
-
int c;
while((c=getchar())!=EOF){
}
I try to read a char each time from stdin and check if it's "\n". However the condition (token != "\n") never returns False and the loop is never broken.
那是因为:
while (token != "\n") {
是一个错误。那应该是:
while (token != '\n') {
您的编译器应该对该错误发出警告。这是我使用 gcc -Wall
:
编译程序时得到的结果
soc.c: In function ‘main’:
soc.c:25:18: warning: comparison between pointer and integer [enabled by default]
while (token != "\n") {
^
soc.c:25:18: warning: comparison with string literal results in unspecified behavior [-Waddress]
为了更安全,使用:
while (token != '\n' && token != EOF ) {
此外,您应该将用于 token
的类型从 char
更改为 int
。 Return fgetc()
的类型是 int
。如果您的平台对 char
使用 unsigned
类型,您将 运行 遇到捕获 EOF
的问题,通常是 -1
.
下面是贴出的代码,有注释..
// <-- strongly suggest reading the manual for the system functions you use
// so the error on the returned value from fgetc() would not have happened
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, const char* argv[])
{
char token; // <-- fgetc and getchar return integer, not character
int n;
if (argc != 2)
{
printf("Error!\n"); // <-- this should be a 'usage' statement
exit(0); // <-- this exit is due to an error, returned value should be a non-zero value to indicate an error occurred
}
// implied else, right number of parameters.
n = atoi(argv[1]); // <-- check that 'n' is not zero and not negative and <= 255
// <-- output an error message and exit of value is not good
// implied else, parameter valid
int i;
int freq[n];
for(i = 0; i<n; i++)
{
freq[i] = 0;
}
int value;
printf(">");
// <-- suggest modification to while(), so fgetc() embedded in while statement
token = fgetc(stdin);
while (token != "\n") { // <-- this is a comparison between pointer and integer, compiler warning
// <-- comparions with string literal results in unspecified behavior
printf("here!");
// <-- token, after correcting declartion to int eliminates the need for 'value'
value = token;
if (value < n) {
freq[value] ++;
}
token = fgetc(stdin);
}
printf("there");
for(i = 0; i<n; i++) {
printf("%d occured %d times\n",i, freq[i]);
}
return 1; // <-- this is the 'good' exit, so should return 0
}
通常,您要执行的操作是通过执行以下操作来完成的:
int ch;
while((ch = getchar()) != '\n' && ch != EOF)
{
// ...
}
所以基本上我正在编写一个 C 程序,它从标准输入读取字节流并将字节视为 0 到 255 范围内的无符号整数。该程序计算 0 到 255 范围内的每个值出现的频率。它还接受一个非负整数作为命令行
争论。此命令行参数给出程序应生成的输出行数 n。因此,如果 n 为 16,程序应打印 16 行输出,显示 0 到 15 范围内的字节值出现的频率。
每行应以整数值开头,后跟计数,例如
0出现1014次
1 出现 1201 次
等等。
我尝试每次从标准输入读取一个字符并检查它是否为“\n”。然而,条件 (token != "\n") 永远不会 returns False 并且循环永远不会中断。
这是我的代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, const char* argv[]) {
char token;
int n;
if (argc != 2) {
printf("Error!\n");
exit(0);
}
n = atoi(argv[1]);
int i;
int freq[n];
for(i = 0; i<n; i++) {
freq[i] = 0;
}
int value;
printf(">");
token = fgetc(stdin);
while (token != "\n") {
printf("here!");
value = token;
if (value < n) {
freq[value] ++;
}
token = fgetc(stdin);
}
printf("there");
for(i = 0; i<n; i++) {
printf("%d occured %d times\n",i, freq[i]);
}
return 1;
}
您可以使用 getchar();
-
int c;
while((c=getchar())!=EOF){
}
I try to read a char each time from stdin and check if it's "\n". However the condition (token != "\n") never returns False and the loop is never broken.
那是因为:
while (token != "\n") {
是一个错误。那应该是:
while (token != '\n') {
您的编译器应该对该错误发出警告。这是我使用 gcc -Wall
:
soc.c: In function ‘main’: soc.c:25:18: warning: comparison between pointer and integer [enabled by default] while (token != "\n") { ^ soc.c:25:18: warning: comparison with string literal results in unspecified behavior [-Waddress]
为了更安全,使用:
while (token != '\n' && token != EOF ) {
此外,您应该将用于 token
的类型从 char
更改为 int
。 Return fgetc()
的类型是 int
。如果您的平台对 char
使用 unsigned
类型,您将 运行 遇到捕获 EOF
的问题,通常是 -1
.
下面是贴出的代码,有注释..
// <-- strongly suggest reading the manual for the system functions you use
// so the error on the returned value from fgetc() would not have happened
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, const char* argv[])
{
char token; // <-- fgetc and getchar return integer, not character
int n;
if (argc != 2)
{
printf("Error!\n"); // <-- this should be a 'usage' statement
exit(0); // <-- this exit is due to an error, returned value should be a non-zero value to indicate an error occurred
}
// implied else, right number of parameters.
n = atoi(argv[1]); // <-- check that 'n' is not zero and not negative and <= 255
// <-- output an error message and exit of value is not good
// implied else, parameter valid
int i;
int freq[n];
for(i = 0; i<n; i++)
{
freq[i] = 0;
}
int value;
printf(">");
// <-- suggest modification to while(), so fgetc() embedded in while statement
token = fgetc(stdin);
while (token != "\n") { // <-- this is a comparison between pointer and integer, compiler warning
// <-- comparions with string literal results in unspecified behavior
printf("here!");
// <-- token, after correcting declartion to int eliminates the need for 'value'
value = token;
if (value < n) {
freq[value] ++;
}
token = fgetc(stdin);
}
printf("there");
for(i = 0; i<n; i++) {
printf("%d occured %d times\n",i, freq[i]);
}
return 1; // <-- this is the 'good' exit, so should return 0
}
通常,您要执行的操作是通过执行以下操作来完成的:
int ch;
while((ch = getchar()) != '\n' && ch != EOF)
{
// ...
}