我注意到了一件直接的事情。您的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