fgets打印出“à”而不是实际输入

时间:2017-09-24 17:34:59

标签: c unix input user-input fgets

我正在尝试用C编写一个程序,以便它从用户那里获取输入,只能是'Q''q''N''n''1'或'2',其他一切都应该是无效的。我是C的新手,因此我仍然无法弄清楚fgets如何工作。无论我输入什么作为输入都是'à'。

char C=' ';
int N=0;

int flag=1;
char buffer[20];
char input[20];
printMenu();
printf("\n\nPlease choose something: ");

fgets(buffer, sizeof(buffer), stdin);
sscanf(buffer, "$s",&input);
//checking the input, shows à instead of an actual input
printf("Input is %c\n", input);

if(*input=='C'||*input=='c')
                C=userInputChar();
        else
                if(*input=='N'||*input=='n')
                        N=userInputInt();
                else
                        if(*input=='1')
                                printTriangleLeft(C,N);
                        else
                                if(*input=='2')
                                        printTriangleRight(C,N);
                                else
                                        if(input[0]=='Q'||input[0]=='q'){
                                                printf("Exiting the program...");
                                                return 0;
                                        }
                                        else
                                                printf("Invalid input");

4 个答案:

答案 0 :(得分:0)

您未检查sscanf的返回值,因此您不知道它是否已成功解析任何内容。

您的$s格式字符串为&input,它不会提取任何值。 scanf参数被忽略。此外,没有char (*)[20]格式,无论如何都会采用printf类型的参数。

%c int需要char *。您已将*input=='C'传递给它。这就是你获得垃圾输出的原因。

*input无法正常工作,因为updatePages()此时尚未初始化。

答案 1 :(得分:0)

您不应该将数组指针传递给sscanf。 数组本身就够了,$ s也不正确。 '%S'你应该用来获取字符串 正确如下:

sscanf(缓冲区,"%s",输入);

答案 2 :(得分:0)

更改了以下内容:     char buffer [20];     char输入[20];

printf("\n\nPlease choose something: ");

fgets(buffer, sizeof(buffer), stdin);
sscanf(buffer, "$s",&input);

printf("Input is %c\n", input);

char buffer[20];
char input;
fgets(buffer, sizeof(buffer), stdin);
sscanf(buffer, "%c",&input);
printf("Input is %c\n", input);

似乎至少对一个角色起作用

答案 3 :(得分:0)

继续我的评论,除了您在代码中遇到的各种语法错误之外,您只是让自己变得更难以实现。在这里,如果我正确理解您的问题,您希望获取输入并验证它仅由字符"Qqn12"组成。

要验证您的输入完全由"Qqn12"组成,您需要遍历输入缓冲区中的每个字符并检查它是"Qqn12"中的一个字符。如果不是输入无效。

在我们到达之前,让我们谈谈验证和删除由'\n'填充的缓冲区中包含的fgets的正确方法(POSIX getline还包括尾随'\ n'在它缓冲区也是如此)。要删除尾随换行符,您可以使用strrchr找到它,也可以使用strlen来获取缓冲区的长度并检查buffer[len - 1] == '\n'。如果buffer[len - 1]不等于'\n',那么您知道stdin中的字符未读(因为stdin中的字符数等于或超过缓冲区大小)并且您需要处理那个错误。例如,您可以使用以下内容:

    char buf[MAXC] = "";
    size_t len;

    printf ("enter string: ");  /* prompt, read and validate */
    if (!fgets (buf, MAXC, stdin)) {
        fprintf (stderr, "error: invalid input or user canceled.\n");
        return 1;
    }

    len = strlen (buf);                 /* get buf length */
    if (len && buf[len-1] == '\n')      /* check for '\n' */
        buf[--len] = 0;                 /* overwrite with '\0' */
    else {  /* input equals or exceeds buffer size, '\n' not read  */
        fprintf (stderr, "error: input exceed %d chars.\n", MAXC-2);
        return 1;
    }

注意测试条件len && buf[len-1] == '\n',您必须在测试len > 0之前检查buf[len-1] == '\n',或者调用未定义的行为通过尝试读取负数组索引。)

接下来,您希望将输入限制为仅选定的字符,因此请创建一个包含您将接受的字符的字符串文字,例如char *accept = "Qqn12";string.h提供strchr函数,该函数将查找并返回指向字符串c中给定字符s的第一个匹配项的指针。声明是:

char *strchr(const char *s, int c);

显然,在缓冲区中查找其中一个字符"Qqn12"没有用,因为其他字符也可能不在"Qqn12"。但是,如果我们围绕进行搜索并询问accept中的每个字符是否都在缓冲区中(例如"Qqn12"之一”,那么你完全具备您正在寻找的测试 - strchr为您扫描accept中的每个字符的工作。例如,您可以执行以下操作:

    ...
    char *accept = "Qqn12";
    ...
    for (char *p = buf; *p; p++)        /* for each char in buf */
        if (!strchr (accept, *p)) {     /* if not in 'accept', error */
            fprintf (stderr, "error: invalid input '%c'.\n", *p);
            return 1;
        }

如果你对数组索引比指针更熟悉,你可以简单地使用数组索引迭代缓冲区中的每个字符,例如:以下内容完全相同:

    for (int i = 0; buf[i]; i++)        /* for each char in buf */
        if (!strchr (accept, buf[i])) { /* if not in 'accept', error */
            fprintf (stderr, "error: invalid input '%c'.\n", buf[i]);
            return 1;
        }

(如果您愿意,甚至可以使用i < len代替buf[i]作为退出条件。

将所有部分放在一起,您可以使用以下内容验证由"Qqn12"组成的条目:

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

#define MAXC 512

int main (void) {

    char buf[MAXC] = "",
        *accept = "Qqn12";
    size_t len;

    printf ("enter string: ");  /* prompt, read and validate */
    if (!fgets (buf, MAXC, stdin)) {
        fprintf (stderr, "error: invalid input or user canceled.\n");
        return 1;
    }

    len = strlen (buf);                 /* get buf length */
    if (len && buf[len-1] == '\n')      /* check for '\n' */
        buf[--len] = 0;                 /* overwrite with '\0' */
    else {  /* input equals or exceeds buffer size, '\n' not read  */
        fprintf (stderr, "error: input exceed %d chars.\n", MAXC-2);
        return 1;
    }

    for (char *p = buf; *p; p++)        /* for each char in buf */
        if (!strchr (accept, *p)) {     /* if not in 'accept', error */
            fprintf (stderr, "error: invalid input '%c'.\n", *p);
            return 1;
        }

    printf ("valid input : %s\n", buf);

    return 0;
}

示例使用/输出

$ ./bin/validinput
enter string: Qqn12n21Qq
valid input : Qqn12n21Qq

$ ./bin/validinput
enter string: Qqn12n21Qbq
error: invalid input 'b'.

仔细看看,如果您有任何其他问题,请告诉我。