我必须编写一个程序,从英语翻译成猪拉丁语,反之亦然,作为一个介绍类,我不明白为什么在验证不接受字母输入后,它不会继续到我的switch语句。这是我的代码的一部分:
int main()
{
char choice;
while (1) {
printf("Press 1 to translate from English to pig Latin.\nPress 2 to translate from pig Latin to English.\nPress 3 to terminate the program.\nEnter your choice.\n");
scanf("%s",&choice);
if (isalpha (choice)) {
printf ("ERROR: Please enter a valid input\n");
continue;
}
switch (choice) {
case 1:
printf("Enter the English sentence.\n");
scanf("%s",str);
englishToPig();
break;
case 2:
printf("Enter the pig Latin sentence.\n");
scanf("%s",str);
pigToEnglish();
break;
case 3:
return 0;
default:
printf("Wrong Choice\n");
break;
}
}
return 0;
}
编辑:交换机在技术上确实有效,但每当我输入1,2或3时,它立即默认为“错误选择”而不是调用我的翻译功能(或退出程序)
答案 0 :(得分:2)
我认为您应该使用int choice
而不是char choice
,然后将scanf
从%s
更改为%d
答案 1 :(得分:0)
您使用了字符串标记%s
而不是%c
,最好使用int
而不是char
。希望它有所帮助!
答案 2 :(得分:0)
将选择的数据类型设置为int 并更改scanf("%d",& choice); 像这样
答案 3 :(得分:0)
虽然您可以使用scanf
来获取用户输入,但您不应该这样做。等待捕获与其使用相关的新C程序员有很多陷阱。要正确使用它,您必须始终验证其返回并处理以下情况:
stdin
取消输入(返回为EOF
);和每次输入都必须这样做。不同的转换说明符如何处理前导空格(数字和EOF
忽略前导空格,字符和字符类(例如%s
)不这样做,这进一步复杂化。
这就是采用用户输入的首选方法是%[..]
(或POSIX fgets
)。两者都是面向行的输入函数,它们读取(包括)尾随getline
(由用户按Enter键生成)。您仍然必须验证两者的返回并根据需要处理尾随'\n'
,但由于未能解释未读的字符而陷入陷阱的可能性会显着降低。
考虑到上述情况,并为'\n'
和choice
使用固定缓冲区(传递给函数str
等...),你可以做点什么简单如下。
首先,您需要在代码englishToPig
中使用一个(或更多)常量。请勿在代码中使用幻数。此外,不要将文本行留在页面的一侧,预处理器将组合所有由空格分隔的字符串文字。这样可以使菜单提示的输出整理一下:
#define
使用#define MAXC 256 /* if you need a constant, define one */
int main (void) {
char choice[MAXC] = "", /* initialize choice and str all zero */
str[BUFSIZ] = ""; /* BUFSIZ is 8092 Linux (512 windows) */
size_t len = 0; /* variable for string length tests */
while (1) {
printf ("\nPress 1 to translate from English to pig Latin.\n"
"Press 2 to translate from pig Latin to English.\n"
"Press 3 to terminate the program.\n\n"
"Enter your choice: ");
...
阅读很简单,fgets
。要验证缓冲区中是否有良好的输入,只需检查返回值是否为fgets (buffer, size, FILE* stream)
。然后,继续检查长度,确保输入符合NULL
个字符,最后一个字符为size
(否则字符仍未读取)。如果您正在存储字符串,或者不记录最后一个字符为'\n'
,则可以通过用'\n'
覆盖它来删除它(与0
相同 - 无字符)
阅读选择很简单:
'\0'
现在您已在 /* read choice (up to 255-chars + nul-terminating char */
if (fgets (choice, MAXC, stdin) == NULL) {
fprintf (stderr, "(user canceled input)\n");
break;
}
len = strlen (choice); /* test all chars fit in choice */
if (len == MAXC - 1 && choice[len - 1] != '\n') {
fprintf (stderr, "warning: characters remain unread.\n");
while (fgets (str, BUFSIZ, stdin)) {} /* read/discard chars */
}
中输入了用户输入,您只需将第一个字符与choice
语句中的每个case
进行比较即可。这就像将解除引用的switch
传递给choice
一样简单(即switch
只是指向第一个字符的指针,因此dereferncing返回第一个字符本身,choice
等效到*choice
)
choice[0]
上面的(注意:>,即使用户输入的大小超过 switch (*choice) { /* *choice is the same as choice[0] */
case '1':
printf ("Enter the English sentence.\n");
/* read input in BUFSIZ chunks, passing str to englishToPig */
while (fgets (str, BUFSIZ, stdin)) {
puts ("calling englishToPig (str)");
// englishToPig (str);
if (str[strlen (str) - 1] == '\n') /* all read, break */
break;
}
break;
case '2':
printf ("Enter the pig Latin sentence.\n");
/* read input in BUFSIZ chunks, passing str to pigtoEnglish */
while (fgets (str, BUFSIZ, stdin)) {
puts ("calling pigtoEnglish (str)");
// pigtoEnglish (str);
if (str[strlen (str) - 1] == '\n') /* all read, break */
break;
}
break;
case '3':
return 0;
default:
fprintf (stderr, "error: invalid choice.\n");
break;
}
,整个输入也会以BUFSIZ
块的形式传递给您的函数。
将上述内容转换为简短示例,只需添加标题和BUFSIZ
,例如
return
以上处理所有正确或无效输入的情况,并处理用户在每个阶段生成手册#include <stdio.h>
#include <string.h>
#define MAXC 256 /* if you need a constant, define one */
int main (void) {
char choice[MAXC] = "", /* initialize choice and str all zero */
str[BUFSIZ] = ""; /* BUFSIZ is 8092 Linux (512 windows) */
size_t len = 0; /* variable for string length tests */
while (1) {
printf ("\nPress 1 to translate from English to pig Latin.\n"
"Press 2 to translate from pig Latin to English.\n"
"Press 3 to terminate the program.\n\n"
"Enter your choice: ");
/* read choice (up to 255-chars + nul-terminating char */
if (fgets (choice, MAXC, stdin) == NULL) {
fprintf (stderr, "(user canceled input)\n");
break;
}
len = strlen (choice); /* test all chars fit in choice */
if (len == MAXC - 1 && choice[len - 1] != '\n') {
fprintf (stderr, "warning: characters remain unread.\n");
while (fgets (str, BUFSIZ, stdin)) {} /* read/discard chars */
}
switch (*choice) { /* *choice is the same as choice[0] */
case '1':
printf ("Enter the English sentence.\n");
/* read input in BUFSIZ chunks, passing str to englishToPig */
while (fgets (str, BUFSIZ, stdin)) {
puts ("calling englishToPig (str)");
// englishToPig (str);
if (str[strlen (str) - 1] == '\n') /* all read, break */
break;
}
break;
case '2':
printf ("Enter the pig Latin sentence.\n");
/* read input in BUFSIZ chunks, passing str to pigtoEnglish */
while (fgets (str, BUFSIZ, stdin)) {
puts ("calling pigtoEnglish (str)");
// pigtoEnglish (str);
if (str[strlen (str) - 1] == '\n') /* all read, break */
break;
}
break;
case '3':
return 0;
default:
fprintf (stderr, "error: invalid choice.\n");
break;
}
}
return 0;
}
(它将在EOF
退出,并在choice
时简单地重新提示
示例使用/输出
使用有效输入:
str
通过按 Ctrl + d (Windows with legacy mode enabled on Win10上的 Ctrl + z )生成手动$ ./bin/fgetspig
Press 1 to translate from English to pig Latin.
Press 2 to translate from pig Latin to English.
Press 3 to terminate the program.
Enter your choice: 1
Enter the English sentence.
My dog has two fleas and my cat has none :)
calling englishToPig (str)
Press 1 to translate from English to pig Latin.
Press 2 to translate from pig Latin to English.
Press 3 to terminate the program.
Enter your choice: 2
Enter the pig Latin sentence.
yMa atca owna asha wota easlfa, uckyla ogda.
calling pigtoEnglish (str)
Press 1 to translate from English to pig Latin.
Press 2 to translate from pig Latin to English.
Press 3 to terminate the program.
Enter your choice: 3
,无效输入和用户取消:
EOF
仔细看看,如果您有其他问题,请告诉我。