简体   繁体   English

使用fgets和strtol获取单个整数

[英]Using fgets and strtol to get a single integer

I am learning C and I am trying to use fgets() and strtol() to accept user input and just take the first character. 我正在学习C,我正在尝试使用fgets()strtol()接受用户输入,只需要取第一个字符。 I am going to make a menu that will allow a user to select options 1-3 and 4 to exit. 我将创建一个菜单,允许用户选择选项1-3和4退出。 I want each option to only be selected if '1', '2', '3', or '4' are selected. 我希望只有在选择“1”,“2”,“3”或“4”时才能选择每个选项。 I don't want 'asdfasdf' to work. 我不希望'asdfasdf'工作。 I also don't want '11212' to select the first option since it starts with a 1. I created this code so far while I started testing and for some reason this loops over the question and supplies a 0 to the input. 我也不希望'11212'选择第一个选项,因为它从1开始。到目前为止我创建了这个代码,当我开始测试时,由于某种原因,这循环问题并为输入提供0。

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

int main() {
    char a[2];
    long b;

    while(1) {
        printf("Enter a number: ");

        fgets(a, 2, stdin);

        b = strtol(a, NULL, 10);

        printf("b: %d\n", b);
    }
  return 0;
}

output 产量

Enter a number: 3
b: 3
Enter a number: b: 0
Enter a number:

It should be: 它应该是:

Enter a number: 3
b: 3
Enter a number: 9
b: 9

You need to have enough room for the '\\n' to be read or else it will be left in the input buffer and the next iteration it will be read immediately and thus make fgets() return with an empty string and hence strtol() returns 0 . 您需要有足够的空间来读取'\\n' ,否则它将被保留在输入缓冲区中,下一次迭代将立即读取,从而使fgets()返回一个空字符串,因此strtol()返回0

Read fgets() 's documentation, it reads until a '\\n' or untill the buffer is full. 读取fgets()的文档,直到'\\n'或直到缓冲区已满为止。 So the first time, it stops because it has no more room to store characters, and then the second time it still has to read '\\n' and it stops immediately. 所以第一次,它停止,因为它没有更多的空间来存储字符,然后第二次仍然必须读取'\\n'并立即停止。

A possible solution is to increase the buffer size, so that the '\\n' is read and stored in it. 一种可能的解决方案是增加缓冲区大小,以便读取'\\n'并将其存储在其中。

Another solution, is to read all remaining characters after fgets() . 另一个解决方案是在fgets()之后读取所有剩余的字符。

The second solution could be cleanly implemented by reading one character at a time instead, since you are just interested in the first character you can discard anything else 第二种解决方案可以通过一次读取一个字符来干净地实现,因为您只对第一个字符感兴趣,您可以丢弃其他任何字符

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

int main() 
{
    int chr;
    while (1) {
        // Read the next character in the input buffer
        chr = fgetc(stdin);
        // Check if the value is in range
        if ((chr >= '0') && (chr <= '9')) {
            int value;
            // Compute the corresponding integer
            value = chr - '0';
            fprintf(stdout, "value: %d\n", value);
        } else {
            fprintf(stderr, "unexpected character: %c\n", chr);
        }
        // Remove remaining characters from the
        // input buffer.
        while (((chr = fgetc(stdin)) != '\n') && (chr != EOF))
            ;
    }
    return 0;
}

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

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