【发布时间】:2015-05-28 16:06:48
【问题描述】:
我正在尝试制作递归菜单。
这个程序稍后将使用树(hojanodo),这就是我跟踪根的原因。
问题:由于某种原因,fgets/fgetc 在第二次运行时在递归内部被跳过,为什么会发生这种情况? 我希望用户输入 1,2 或 3.(int) 有什么办法解决这个问题?这是实现菜单的最佳方式吗?
这就是我现在所拥有的:(它可以编译并运行,因此您可以对其进行测试,但它并没有像我想要的那样真正工作......)
#include<stdio.h>
#include<stdlib.h>
typedef struct node{
char ch;
int i;
struct node *left;
struct node *right;
}hojaNodo;
int handle_menu(int eventHandler, hojaNodo **root);
int opcion_menu();
char get_symbol();
int get_userMenuInput();
int intro();
int main(){
hojaNodo *treeRoot = NULL;
intro();
// system("clear");
handle_menu(opcion_menu(), &treeRoot);
return 0;
}
int opcion_menu(){
int userOption;
printf("1.Agrega un Simbolo.\n");
printf("2.Listar Codigo\n");
printf("3.Exit");
userOption = get_userMenuInput();
printf("User: %d",userOption);
if(userOption < 4 && userOption > 0){
return userOption;
}
else
return -1;
}//eof opcion_menu
int handle_menu(int userOption,hojaNodo **root){
hojaNodo *tempRoot = NULL;
tempRoot = *root;
int valor;
char simbol;
switch(userOption){
case 1:
simbol = get_symbol();
printf("Simbol: %c", simbol);
break;
case 2:
printf("List Nodes\n");
break;
case 3:
printf("Exit");
userOption = -1;
// destroy_tree(root);
break;
default:
printf("userOption Error, Bye!");
break;
}//eof switch
if(userOption != -1)
handle_menu(opcion_menu(),&tempRoot);
// return userOption;
return -1;
}//eof menu()
char get_symbol(){
/*char userKey[3]
fgets(userKey,len,stdin);*/
char simbolo;
printf("Give me a symbol.");
simbolo = fgetc(stdin);
return simbolo;
}
int get_userMenuInput(){
char userKey[3];
int userOption;
size_t len;
len = sizeof(userKey);
fgets(userKey,len,stdin);
userOption = atoi(userKey);
//printf("User Option: %d\n", userOption);
return userOption;
}
【问题讨论】:
-
这一行:'switch(userOption){' 正在使用 userOption,但是,该变量未设置为任何特定值(该变量在 main() 中声明但未设置为任何特定值,所以它包含堆栈中的垃圾,位于 main() 中的位置。看起来变量应该初始化为 1。
-
始终检查 fgets() 和 family 的返回值,以确保操作成功
-
如果用户输入的所有内容都是换行符,则对 fgets() 的调用将仅返回两个字节。 (甚至在 windows/dos 系统上它会返回 3 个字符。)建议将变量 userkey 设置为更长的数组,在对 fgets() 的调用中,第二个参数应该是 'sizeof userKey'' 所以对 userkey 的修改只需要在代码中的一处制作。强烈建议删除主变量 eventhandler 并将对 handle_menu 的调用更改为:handle_menu( opcion_menu(), &tempRoot );
-
main() 总是被声明为返回 int,所以它需要一个“返回值”;就在最后一个右大括号之前的语句。建议在启用所有警告的情况下进行编译,以便编译器可以告诉您它在代码中看到的问题。始终修复警告。他们在那里让你知道编译器认为代码有一些可疑的语法/逻辑
-
switch() 代码块应该在一个循环中,提示输入用户输入,直到输入有效值(1、2、3、-1)。如果递归非常深,则消息“userOption Error,Bye!”将为每个级别的递归输出。注意:用户不能通过调用 fgets() 将“-1”输入到只有 2 个字节长的字符数组中。 fgets 将读取一个字节,附加一个 '\0' 并返回。所以数组中的所有内容都是 '-','\0'
标签: char stdin scanf fgets fgetc