我正在尝试用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");
答案 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'.
仔细看看,如果您有任何其他问题,请告诉我。