简体   繁体   English

在此示例中,我不了解fgets的行为

[英]I don't understand the behavior of fgets in this example

While I could use strings, I would like to understand why this small example I'm working on behaves in this way, and how can I fix it ? 虽然我可以使用字符串,但我想了解为什么我正在处理的这个小示例会以这种方式运行,以及如何解决?

int ReadInput() {
    char buffer [5];
    printf("Number: ");
    fgets(buffer,5,stdin);
    return atoi(buffer);
}

void RunClient() {
    int number;
    int i = 5;
    while (i != 0) {
        number = ReadInput();
        printf("Number is: %d\n",number);
        i--;
    }
}

This should, in theory or at least in my head, let me read 5 numbers from input (albeit overwriting them). 从理论上或者至少在我的脑海中,这应该让我从输入中读取5个数字(尽管会覆盖它们)。

However this is not the case, it reads 0, no matter what. 但是事实并非如此,无论如何它都读取为0。

I understand printf puts a \\0 null terminator ... but I still think I should be able to either read the first number, not just have it by default 0. And I don't understand why the rest of the numbers are OK (not all 0). 我知道printf放置了\\ 0空终止符...但我仍然认为我应该能够读取第一个数字,而不仅仅是默认情况下为0。而且我不明白为什么其余的数字都可以(并非全为0)。

CLARIFICATION: I can only read 4/5 numbers, first is always 0. 澄清:我只能读取4/5数字,第一个始终为0。

EDIT: 编辑:

I've tested and it seems that this was causing the problem: 我已经测试过,看来这是引起问题的原因:

main.cpp main.cpp中

scanf("%s",&cmd);
    if (strcmp(cmd, "client") == 0 || strcmp(cmd, "Client") == 0)
        RunClient();

somehow. 不知何故。

EDIT: 编辑:

Here is the code if someone wishes to compile. 如果有人希望编译,请参见以下代码。 I still don't know how to fix 我仍然不知道如何解决

http://pastebin.com/8t8j63vj http://pastebin.com/8t8j63vj

FINAL EDIT: 最终编辑:

Could not get rid of the error. 无法摆脱错误。 Decided to simply add @ReadInput 决定只添加@ReadInput

int ReadInput(BOOL check) {
    ...
    if (check) 
       printf ("Number: ");
    ...

@ RunClient() @ RunClient()

void RunClient() {
    ...
    ReadInput(FALSE); // a pseudo - buffer flush. Not really but I ignore 
    while (...) {                    // line with garbage data
        number = ReadInput(TRUE);
        ...
    }

And call it a day. 并称之为一天。

fgets reads the input as well as the newline character. fgets读取输入以及换行符。 So when you input a number, it's like: 123\\n . 因此,当您输入数字时,就像: 123\\n

atoi doesn't report errors when the conversion fails. 转换失败时atoi不会报告错误。

Remove the newline character from the buffer : buffer删除换行符:

buf[5];
size_t length = strlen(buffer);
buffer[length - 1]=0;

Then use strtol to convert the string into number which provides better error detection when the conversion fails. 然后,使用strtol将字符串转换为数字,以便在转换失败时更好地检测错误。

char * fgets ( char * str, int num, FILE * stream );

Get string from stream. 从流中获取字符串。

Reads characters from stream and stores them as a C string into str until (num-1) characters have been read or either a newline or the end-of-file is reached, whichever happens first. 从流中读取字符,并将它们作为C字符串存储到str中,直到已读取(num-1)个字符或到达换行符或到达文件末尾为止,以先发生的为准。

A newline character makes fgets stop reading, but it is considered a valid character by the function and included in the string copied to str. 换行符使fgets停止读取,但该函数将其视为有效字符并包含在复制到str的字符串中。 (This means that you carry \\n) (这意味着您携带\\ n)

A terminating null character is automatically appended after the characters copied to str. 复制到str的字符后会自动附加一个终止的字符。 Notice that fgets is quite different from gets: not only fgets accepts a stream argument, but also allows to specify the maximum size of str and includes in the string any ending newline character. 请注意,fgets与gets有很大的不同:fgets不仅接受流参数,还允许指定str的最大大小,并在字符串中包括任何结尾的换行符。

PD: Try to have a larger buffer. PD:尝试使用更大的缓冲区。

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

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