繁体   English   中英

fgets 和 sscanf 在 c 中被跳过?

[英]fgets and sscanf being skipped in c?

在我的代码中,我确保用户输入以下缩写类之一,但是我的 fgets 导致我出现很多逻辑错误。

char class[3];
char arr3[5];
i = 0;
    while(i == 0){
        printf("Enter the class, either FR, SO, JR, SR, GR, RFR, or RSO\n");
        fgets(arr3, sizeof(arr3), stdin);

        if(sscanf(arr3, "%s", class) == 1){

            if(strcmp(class, "FR\0") == 1 || strcmp(class, "SO\0") == 1)
                i = 1;
            else if(strcmp(class, "JR\0") == 1 || strcmp(class, "SR\0") == 1)
                i = 1;
            else if(strcmp(class, "GR\0") == 1 || strcmp(class, "RFR\0") == 1)
                i = 1;
            else if(strcmp(class, "RSO\0") == 1)
                i = 1;
            else
                printf("Enter one of the classes.  Must be all caps.\n");
        }
        else if(sscanf(arr3, "%s", class) != 1)
            printf("An error has occured.\n");
    }

当我运行代码时,首先发生的事情是它跳过 fgets,然后打印:Enter one of the classes。 必须全部大写。 这是否意味着它正在读取标准输入中已经存在的内容?

继续我的评论,你有很多错误,但最大的错误是不要吝啬缓冲区大小! . 您的下一个主要混淆点是当字符串匹配时strcmp返回零,而不是1 不要尝试通过截断为更短的数组来删除fgets包含的尾随'\n' ,只需使用strcspn将其删除。

String Literal提供了nul-termianting字符,因此"SR\0" "\0"中的“\0”是多余的。 摆脱他们。

但是,恭喜,您获取用户输入的基本方法(例如循环不断地强制用户输入所需内容)是正确的方法。

进行这些更改您可以:

#include <stdio.h>
#include <string.h>

#define BUFC 1024       /* if you need a constant, #define one (or more) */

int main (void) {

    char buf[BUFC];

    while (1) {
        printf("Enter the class, either FR, SO, JR, SR, GR, RFR, or RSO\n");
        if (!fgets (buf, BUFC, stdin)) {
            fputs ("(user canceled input)\n", stdout);
            return 1;
        }
        buf[strcspn (buf, "\n")] = 0;       /* trim newline from buf */

        /* strcmp equality return is 0 */
        if (strcmp (buf, "FR") == 0 || strcmp (buf, "SO") == 0  ||
            strcmp (buf, "JR") == 0 || strcmp (buf, "SR") == 0  ||
            strcmp (buf, "GR") == 0 || strcmp (buf, "RFR") == 0 ||
            strcmp (buf, "RSO") == 0)
            break;
        else
            printf("Enter one of the classes.  Must be all caps.\n");
    }
    printf ("\nclass: %s\n", buf);
}

注意:如果你是为微控制器编译的,比如 Arduino 或 TI-MSP432,内存有限,那么你可以将BUFC减少到32左右,但在 x86 或 x86_64 上,1K 到 4K 的缓冲区通常可以确保所有正常线路遇到的输入将被消耗——即使猫踩在键盘上)

在上面,检查fgets()的返回允许您捕获手动生成的EOF ,其中用户通过在 Linux 上按Ctrl+d或在 Windows 上按 Ctrl+z取消输入。

示例使用/输出

$ ./bin/enterclasses
Enter the class, either FR, SO, JR, SR, GR, RFR, or RSO
banannas
Enter one of the classes.  Must be all caps.
Enter the class, either FR, SO, JR, SR, GR, RFR, or RSO
NO
Enter one of the classes.  Must be all caps.
Enter the class, either FR, SO, JR, SR, GR, RFR, or RSO
RFR

class: RFR

检查一下,如果您还有其他问题,请告诉我。

暂无
暂无

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

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