0
votes

I'm creating a file management program for a project in C and I have this error which is probably obvious to most programmers but since I'm really bad I can't spot what I have done wrong. My main program is an interface which asks users for a file name and assigns it to the array fileName.

int main() {
    char fileName[50];
    assignFileName(fileName);
    char option[2];
    int checkInput;
    do {
        printf("File management program. Options :\n '1' for File operations (Create, copy, delete or display file)\n '2' for Line operations (Append, delete, display or insert line to file)\n '3' for General operations (Display change log or number of lines for file)\n '4' to select a new file\n '9' to exit program\n");
        printf("aaa %s\n", fileName); //first printf check - prints "aaa" and value in fileName
        checkInput = checkUserInput(option);
        printf("aaa %s\n", fileName); // second printf check = prints only "aaa"
        if (checkInput == 1) {
          //... etc
        }
void assignFileName(char *fileName) {
    printf("Enter file name to operate on, or 'E' to exit the program.\n");
    do {
        if ((fgets(fileName, 50, stdin)) != NULL) {
            if (fileName[strlen(fileName)-1] = '\n') {
                fileName[strlen(fileName)-1] = '\0'; 
            }
            if (strlen(fileName) == 1 && *fileName == 'E') {
                exit(0);
            } else if (strlen(fileName) == 0) {
                printf("Error : Please enter a file name or 'E' to exit.\n");
            }
        } else {
            perror("Error assigning file name ");
        }
        
    } while (strlen(fileName) == 0);
}

I'm fairly sure this code is fine. There's probably lots of ways to make it more efficient and if anyone wants to offer their input I will take it into account. However, the problem is later on in the code. I have 2 printf statements to check the value of fileName. After the first one, everything seems to be alright but then the for the second one the value of fileName seems to be cleared, so something is clearly happening in checkUserInput. All checkUserInput does is check the user enters a single digit number :

void flush() {
    int ch;
    while ((ch = getchar()) != '\n' && ch != EOF) {
    }
}

int checkUserInput(char *input) {
    if (fgets(input, 3, stdin) != NULL) {
        printf("you entered %c\n", input[0]);
        if (input[1] == '\n') {
            return 1;
        } else {
            flush();
            printf("Error : Please enter one of the options given.\n");
        }
    } else {
        printf("Error : Please try again.\n");
    }
    return 0; 
}

I put more printf statements to error check and it seems after the call to fgets(input, 3, stdin) the value in fileName is cleared. Can anyone explain to me why this is the case? I'm not even passing the array fileName to checkUserInput so I don't even know how the program is changing it. This is a link to what the console displayed : (can't post images sorry not 10 rep). https://cdn.discordapp.com/attachments/708320229737889832/802557193043050516/unknown.png

All help would be very appreciated. Thanks.

2
You assign a newline instead of comparing with a new line. - Jonathan Leffler
Omg thank u i didn't notice that error in assignFileName. However error still occurs after fixing that - Joshua Lawson
checkUserInput(option) reads 3 bytes into an array of size 2. - Nate Eldredge
What Nate said. For a single-letter input, you'll need at least three characters in fgets: the letter, the new-line and the null terminator. Writing the terminator is out of bounds. (Don't be stingy with char buffers. Make them a reasonable size, even if the user is supposed to enter only single-letter commands.) - M Oehm
Your compiler should have warning options that you should use. If it doesn't, get a better compiler. I noticed the assignment vs comparison problem. I didn't read the rest of the code to work out why there's a problem. - Jonathan Leffler

2 Answers

1
votes

if (fileName[strlen(fileName)-1] = '\n') should be:

if (fileName[strlen(fileName)-1] == '\n') 

Note that you can strip the trailing newline with this simple line:

filename[strcspn(filename, "\n")] = '\0';
0
votes

error was char option[2] when it should be char option[3]. Thanks to @Nate Eldredge and @M Oehm