0

Very new to C programming. I'm writing a program where I want to prompt the user to input the name of the file to be open for reading. On my code shown bellow I want to throw an error if it doesn't open or if the file doesn't exist, but when I run it, my code blows up and I have to close the program (DOS)

/*ask user for the name of the file*/
  printf("enter file name: ");
  gets(fname);


//Opens the file from where the text will be read. 
fp=fopen(fname, "r");

//Checks if the file us unable to be opened, then it shows the error message 
if (fp == NULL)
    {
     printf("\nError, Unable to open the file for reading\n");
    }

// you can test this by creating a name.txt file. Please let me know if you need additional information.

NewLearner
  • 213
  • 2
  • 6
  • 16
  • 7
    How have you defined `fname`? Oh, and please, please, please don't use `gets` -- ever! Consider `fgets` as one possible alternative. – Jerry Coffin Apr 11 '12 at 03:59
  • You should also be clear about what you mean when you say "when I run it", especially if you're new to C. Do you mean it doesn't compile, it crashes immediately on run, or it crashes after you try to enter a file name and push enter? – merlin2011 Apr 11 '12 at 04:04

3 Answers3

5

Well, you should make sure there's enough room in fname to store your file name, otherwise you'll almost certainly cause corruption and "blowing up" :-)

For example, the following snippet:

char fname[10];
gets (fname);

will be problematic if you enter more information than fname can hold. At that point, you're into undefined behaviour territory and anything can happen.

But, because gets provides no way to limit what the user enters, you should never use it!

A proper, protected, method of user input can be found in this answer.

It uses fgets since that can limit what the user enters. It also allows for a prompt, provides an error indication if something goes wrong, handles end-of-file correctly, and removes the remainder of any too-large line so that it cannot affect the next input operation.

In fact, I'll copy it here to make this answer self-contained:

#include <stdio.h>
#include <string.h>

#define OK       0
#define NO_INPUT 1
#define TOO_LONG 2
static int getLine (char *prmpt, char *buff, size_t sz) {
    int ch, extra;

    // Get line with buffer overrun protection.
    if (prmpt != NULL) {
        printf ("%s", prmpt);
        fflush (stdout);
    }
    if (fgets (buff, sz, stdin) == NULL)
        return NO_INPUT;

    // If it was too long, there'll be no newline. In that case, we flush
    // to end of line so that excess doesn't affect the next call.
    if (buff[strlen(buff)-1] != '\n') {
        extra = 0;
        while (((ch = getchar()) != '\n') && (ch != EOF))
            extra = 1;
        return (extra == 1) ? TOO_LONG : OK;
    }

    // Otherwise remove newline and give string back to caller.
    buff[strlen(buff)-1] = '\0';
    return OK;
}

You can call it as follows, specifying the buffer and size, and receiving an error indication on return:

// Test program for getLine().

int main (void) {
    int rc;
    char buff[10];

    rc = getLine ("Enter string> ", buff, sizeof(buff));
    if (rc == NO_INPUT) {
        // Extra NL since my system doesn't output that on EOF.
        printf ("\nNo input\n");
        return 1;
    }

    if (rc == TOO_LONG) {
        printf ("Input too long [%s]\n", buff);
        return 1;
    }

    printf ("OK [%s]\n", buff);

    return 0;
}
Community
  • 1
  • 1
paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
  • @NewLearner, there are other problems with `scanf`, particularly if you use the 'unbounded string' format string `%s`. It too is subject to buffer overflow. `scanf` means "scan formatted" and there's not much more _unformatted_ than user input :-) Don't get me wrong, it's fine in most cases, especially for learning C, or classwork, or quick-and-dirty programs, but it's no good for production quality code. – paxdiablo Apr 11 '12 at 23:51
0

Not sure what you're missing, but this program compiles and runs for me using cl.exe on the command line.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(){
    char fname[100];
    FILE* fp;
    memset(fname, 0, 100);
    /*ask user for the name of the file*/
    printf("enter file name: ");
    gets(fname);


    //Opens the file from where the text will be read. 
    fp = fopen(fname, "r");

    //Checks if the file us unable to be opened, then it shows the error message 
    if (fp == NULL)
    {
        printf("\nError, Unable to open the file for reading\n");
    }

}

Also note that certain compilers (including Microsoft's) require you to put all declarations at the top of the function when called with default options.

merlin2011
  • 71,677
  • 44
  • 195
  • 329
0

well,This is what happened with me, adding an "else" condition for "if" worked for me.Below mentioned is the code.

#include<stdio.h>
#include<conio.h>
#include<string.h>

int  main() 
{

char fname[100];
FILE* fp;
memset(fname, 0, 100);
/*ask user for the name of the file*/
printf("enter file name: ");
gets(fname);

fp = fopen(fname, "r");

//Checks if the file us unable to be opened, then it shows the error message 
if (fp == NULL)
{
    printf("\nError, Unable to open the file for reading\n");
}

else
{
    printf("hello");
}


getch();
}

Also make sure that you've added "#include" as your header file.