我注意到了一件直接的事情。您的do while
循环正在检查val
的"X"
,而该值实际上是menu
。
除了这种可能性(val
可能是"X"
开头,无论输入的值如何都可能导致退出循环),没有任何内容跳出显然会导致过早退出函数或循环。我想你会更好地发布你的完整代码库,所以我们不会猜测太多。
更新:
不要使用下面的功课 - 你几乎肯定会失败剽窃(因为你的教育者,假设他们不是傻瓜总额,将采取的寻找工作来自这些网站)。
我只是想给你的,你可以使用什么用户I/O,以使你的程序多了几分稳健的想法。作为一个有用的灵魂所指出的,你不应该使用没有缓冲器超限运行的保护作为一个选项,因为这几乎肯定会允许恶意输入到崩溃的代码(这是最好的情况下,输入程序,最坏的情况是,他们将接管你的电脑)。
这意味着没有gets
,您需要使用fgets
,因为它可以限制实际输入的信息量。此外,我倾向于避免使用scanf
和fscanf
因为在这些功能中的任何故障实际离开输入文件指针在一个不确定的位置。
我觉得这是更好的使用fgets
得到一整行,请检查您实际上了一整行,然后在该行中使用sscanf
。这样,你可以肯定你是一个行边界上,你已经有了一个完整的线,你可以再sscanf
该行你的心脏的内容,直到你的东西相匹配。
为此,您可能想看看在下面的代码:
#include <stdio.h>
#define FSPEC "file.txt"
// Skip to the end of the line. This is used in some
// places to ensure there's no characters left in the
// input buffer. It basically discards characters
// from that buffer until it reaches the end of a line.
static void skipLine (void) {
char ch = ' ';
while ((ch != '\n') && (ch != EOF))
ch = getchar();
}
// Get a line of input from the user (with length checking).
static char *getLine (char *prompt, char *line, int sz) {
// Output prompt, get line if available.
// If no line available (EOF/error), output newline.
printf ("%s", prompt);
if (fgets (line, sz, stdin) == NULL) {
printf ("\n");
return NULL;
}
// If line was too long (no '\n' at end), throw away
// rest of line and flag error.
if (line[strlen (line) - 1] != '\n') {
skipLine();
return NULL;
}
// Otherwise line was complete, return it.
return line;
}
// Output the menu and get a choice from the user.
static char doMenu (void) {
char cmd[1+2]; // need space for char, '\n' and '\0'.
// Output the menu.
printf ("\n");
printf ("\n");
printf ("Main menu\n");
printf ("---------\n");
printf ("1. Input a line\n");
printf ("2. Output the file\n");
printf ("3. Clear the file\n");
printf ("\n");
printf ("x. Exit\n");
printf ("\n");
// Get the user input and return it.
if (getLine ("Enter choice (1,2,3,x): ", cmd, sizeof(cmd)) == NULL)
return '\n';
printf ("\n");
return cmd[0];
}
static void doOption1 (void) {
FILE *fh;
char *ln;
char buff[15+2]; // need space for line, '\n' and '\0'.
// Get and check line, add to file if okay.
if ((ln = getLine ("Enter line: ", buff, sizeof(buff))) == NULL) {
printf ("Bad input line\n");
} else {
fh = fopen (FSPEC, "a");
if (fh != NULL) {
fputs (ln, fh);
fclose (fh);
}
}
}
static void doOption2 (void) {
FILE *fh;
int intch;
// Output the file contents.
printf ("=====\n");
fh = fopen (FSPEC, "r");
if (fh != NULL) {
while ((intch = fgetc (fh)) != EOF)
putchar (intch);
fclose (fh);
}
printf ("=====\n");
}
static void doOption3 (void) {
FILE *fh;
// Clear the file.
fh = fopen (FSPEC, "w");
if (fh != NULL)
fclose (fh);
}
// Main program basically just keeps asking the user for input
// until they indicate they're finished.
int main (void) {
char menuItem;
// Get asking for user input until exit is chosen.
while ((menuItem = doMenu()) != 'x') {
switch (menuItem) {
case '1': doOption1(); break;
case '2': doOption2(); break;
case '3': doOption3(); break;
default: printf ("Invalid choice\n"); break;
}
}
return 0;
}
从不使用gets。 EVER。 – 2009-12-03 01:54:16