Одна непосредственная вещь, которую я заметил.Ваш do while
цикл проверяет val
для "X"
, тогда как это значение фактически находится в menu
.
Кроме этой возможности (val
может быть "X"
для начала, что может привести квыход из цикла независимо от введенного значения), ничто не выскакивает, поскольку, очевидно, вызывает преждевременный выход из функции или цикла.Я думаю, вам будет лучше опубликовать полную базу кода, поэтому мы не слишком много гадаем.
Обновление:
Не используйте следующее для домашней работы- вы почти наверняка потерпите неудачу из-за плагиата (поскольку ваши преподаватели, предполагая, что они не абсолютные дураки, будут искать работу, взятую с этих сайтов).
Я просто хотел дать вам представление очто вы можете использовать для пользовательского ввода-вывода, чтобы сделать ваши программы немного более надежными.Как указала одна полезная душа, вы никогда не должны использовать входные подпрограммы, которые не имеют защиты от переполнения буфера, в качестве опции, так как это почти наверняка позволит злонамеренному вводу испортить ваш код (в лучшем случае, в худшемперехватит ваш компьютер).
Это означает, что нет 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;
}