One immediate thing I noticed. Your do while
loop is checking val
for "X"
whereas that value is actually in menu
.
Other than that possibility (val
may be "X"
to begin with, which could cause exit from the loop regardless of the value entered), nothing jumps out as obviously causing premature exit from a function or loop. I think you'll be better off posting your full code base so we're not guessing too much.
Update:
Don't use the following for homework - you will almost certainly be failed for plagiarism (since your educators, assuming they're not total fools, will be on the lookout for work taken from these sites).
I just wanted to give you an idea of what you can use for user I/O to make your programs a little more robust. As one helpful soul pointed out, you should never use the input routines that don't have buffer over-run protection as an option since that will almost certainly allow malicious input to crash your code (that's the best case, worst case is that they will take over your computer).
That means no gets
, you need to use fgets
instead since it can limit how much information is actually input. In addition, I tend to avoid the use of scanf
and fscanf
since any failure in those functions actually leaves the input file pointer at an indeterminate location.
I find it's far better to use fgets
to get a whole line, check that you actually got a whole line, then use sscanf
on that line. That way, you can be sure you're on a line boundary, that you've got an entire line and that you can then sscanf
that line to your heart's content until you match it with something.
To that end, you may want to look over the following code:
#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;
}