简体   繁体   English

每次从stdin读取char的最佳方法是什么?

[英]What is the best way to read a char each time from stdin?

So basically I am writing a C program that reads a stream of bytes from standard input and treats the bytes as unsigned integers in the range 0 to 255 inclusive. 因此,基本上,我正在编写一个C程序,该程序从标准输入读取字节流,并将字节视为0到255之间(含0和255)的无符号整数。 The program counts how often each value in the range 0 to 255 occurs. 程序会计算0到255之间的每个值出现的频率。 It also accepts a nonnegative integer as a command line argument. 它还接受非负整数作为命令行参数。 This command line argument gives the number of lines, ​n, ​of output the program should produce. 此命令行参数给出程序应产生的输出的行数n。 Thus, if​ n​ is 16, the program should print 16 lines of output showing how often the byte values in the range 0 to 15 inclusive occurred. 因此,如果n为16,则程序应打印16行输出,显示出现0到15(含)范围内的字节值的频率。
Each line should begin with the integer value followed by the count, eg 每行应以整数值开头,后跟计数,例如
​0 occurred 1014 times 0发生了1014次
1 occurred 1201 times 1次发生1201次
and so on. 等等。

I try to read a char each time from stdin and check if it's "\\n". 我每次尝试从stdin读取一个字符,并检查它是否为“ \\ n”。 However the condition (token != "\\n") never returns False and the loop is never broken. 但是条件(令牌!=“ \\ n”)从不返回False,循环也永不中断。
Here is my code: 这是我的代码:

#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;
}

I try to read a char each time from stdin and check if it's "\\n". 我每次尝试从stdin读取一个字符,并检查它是否为“ \\ n”。 However the condition (token != "\\n") never returns False and the loop is never broken. 但是条件(令牌!=“ \\ n”)从不返回False,循环也永不中断。

That's because: 那是因为:

while (token != "\n") {

is an error. 是一个错误。 That should be: 应该是:

while (token != '\n') {

Your compiler should warn about that error. 您的编译器应警告该错误。 This is what I get when I compile the program using gcc -Wall : 这就是我使用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]

To be more safe, use: 为了更安全,请使用:

while (token != '\n' && token != EOF ) {

Also, you should change the type used for token from char to int . 另外,您应该将用于token的类型从char更改为int Return type of fgetc() is int . fgetc()返回类型为int If your platform uses unsigned type for char , you will run into problems with capturing EOF , which is often -1 . 如果您的平台对char使用unsigned type,则捕获EOF会遇到问题,通常为-1

you may use getchar(); 您可以使用getchar(); - --

int c;

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

}

the following is the posted code, with comments.. 以下是发布的代码,并带有注释。

// <-- 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
}

Generally, what you're trying to do is accomplished as doing the following: 通常,您要执行的操作是通过执行以下操作来完成的:

int ch;

while((ch = getchar()) != '\n' && ch != EOF)
{
   // ...
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM