• Advertisement
Sign in to follow this  

[Solved!] Help: C's fopen() is not accepting my variables as parameters!

This topic is 3731 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi all, I'm in the process of refreshing my C knowledge with "Absolute Beginner's Guide to C" (very good book if you want a short primer!) and I just reached file handling. Here I have a really big problem: The "fopen()" library function of C which must be used to open any sequential file takes two parameters, the file name and the mode which the file should be opened. Then it should return a pointer to the file (or file Descriptor) if it could open the file successfully. Example: pFilePointer = fopen("MyFile.txt", "r"); Here's the function's prototype: FILE *fopen(const char *filename, const char *mode); Now what I want to do, is ask the user in a simple program if he wants to (R)ead from, (W)rite to or (A)ppend to a file. Then I am asking the user for the file name and storing his answer in a regular character array (string) called fileName. However, when I try to open the file with fopen() like this: -------------------------- FILE * pFilePointer; char[255] fileName; char[3] fileMode; <snip code for getting fileMode and FileName strings form user> pFilePointer = fopen(fileName, fileMode); -------------------------- I don't get the needed file pointer but NULL in return! If I replace the line to this: pFilePointer = fopen("testfile.dat", "w"); everything works just fine and peachy! Even if I enter "testfile.dat" as input for the file name when running the program as a user and have the file name printed to double-check, the file name really is "testfile.dat" but fopen does NOT return a pointer to it if I don't specify the file name hard-coded in a literal string like this: "testfile.dat" :-(( I've tried putting a '&' and a '*' in front of fileName but that just gives me compiler errors (Visual C++ 2005) that it's the wrong type or can't convert. I also created a pointer to the filename variable: char * pFileName = fileName; and then used the pointer as an argument in fopen() but that didn't change anything. What am I doing wrong? :-(( Surely there MUST be a way to use fopen with dynamic / changing file names, is there not? I'm a little desperate here. I tried google but could not find anything on it. All the code examples in books or the web feature either a string literal such as "testfile.dat" or an element of the argv array such as argv[1]. None seem to prompt the user for a file name and then use that. Regards, Mark PS: Mods: If this topic belongs into General Programming Questions, please move it, not sure here, it's about programming but also a noob question... [Edited by - Markie on November 2, 2007 10:05:36 AM]

Share this post


Link to post
Share on other sites
Advertisement
How are you reading the name and mode from the user?

Also, your declarations look wrong there, it should be:

char fileName[255];
char fileMode[3];

Share this post


Link to post
Share on other sites
Debugging 101.

A. When something goes wrong, determine the symptoms (what happens, versus what should actually happen). In this case, you've successfully identified that your call to fopen returned NULL instead of a valid file pointer.

B. Once you know the symptoms, read the manual for your tool to determine what could create those symptoms. You didn't do this. In this particular case:

Quote:
man fopen
Upon successful completion fopen(), fdopen() and freopen() return a FILE
pointer. Otherwise, NULL is returned and the global variable errno is
set to indicate the error.


C. This should let you diagnose the error, by examining the value of errno:

Quote:
man errno
The perror() function produces a message on the standard
error output (file descriptor 2) describing the last error
encountered during a call to a system or library function.


D. The error is usually due to incorrect manipulation (you've called the wrong function, you've provided the wrong variable) or incorrect value (you've provided the right variable, but that variable's value was not the right one). In the first case, correct your manipulation. Otherwise, the incorrect value is a symptom which you should solve by going back to B.

Randomly trying to change your code to see if it works is possibly the worst thing that you could do—it's even worse than letting the bug as-is (you know that bug exists and what it does, but you don't know what subtle bugs you could introduce through random modifications). First, understand why the program doesn't work (you should be able to explain to someone else why it doesn't work), and only then modify it to correct the error.

Share this post


Link to post
Share on other sites
An fopen with mode 'r' will return NULL if the file doesnt exist. Also are you null terminating your mode string.

Share this post


Link to post
Share on other sites
Which function do you use to enter the filename? Check if you are no getting '\n' at the end of your filename.

Share this post


Link to post
Share on other sites
I'd suggest printing the contents of the two variables so you know exactly what you are passing to fopen(). I like to do this as part of my error handling. Here's an example.


FILE *fp;
char filename[255];
char mode[2];

/* Get filename and mode from user. */

if ((fp = fopen(filename, mode)) != NULL)
{
/* Read from the file. */
fclose(fp);
}
else
printf("Couldn't open file - name: %s, mode: %s\n", filename, mode);



Also, like spookycat said, make sure the file exists before you try to open it for reading.

Shawn

Share this post


Link to post
Share on other sites
Thanks a ton!
I found the error [attention]
[totally] [wow] [grin]

You guys are really worth your words in *gold*!
[wink]


Quote:
Original post by spookycat
An fopen with mode 'r' will return NULL if the file doesnt exist. Also are you null terminating your mode string.

Sorry, this was bad communication on my part. Actually I was trying to create a file with "w". I just used "r" for this example, which was obviously a mistake. You're right of course: Reading a file that doesn't exist would indeed have to produce an error of some kind! ;-)

Quote:
Original post by rozz666
Which function do you use to enter the filename? Check if you are no getting '\n' at the end of your filename.

THAT'S IT! That's exactly what was happening!!!
:-))))))))))))))))

I was using fgets to read in the file name from the user because it offers the possibility to limit input characters quite easily.
In "Absloute Beginner's Guide to C, when fgets() is first introduced, it states on page 271, that fgets() works like gets(), except that you specify a length argument.
This is obviously false as I have read up in some more detailed C books now:
Unlike gets() which replaces the new line character of an Enter key press with a string's needed NULL terminating zero, fgets() KEEPS the new line character and only ADDS a NULL terminating zero. Probably this is because fgets() was intended for reading lines from files originally.
So I really had a new line character in my fileName! ...

Thanks rozz666 and Jerax!

Quote:
Original post by ToohrVyk
Debugging 101.

A. When something goes wrong, determine the symptoms (what happens, versus what should actually happen). In this case, you've successfully identified that your call to fopen returned NULL instead of a valid file pointer.

B. Once you know the symptoms, read the manual for your tool to determine what could create those symptoms. You didn't do this. In this particular case:

Quote:

man fopen
Upon successful completion fopen(), fdopen() and freopen() return a FILE
pointer. Otherwise, NULL is returned and the global variable errno is
set to indicate the error.


<snip>

I'm programming with Visual C++, so I don't have man pages at my convenience.
I don't know what you mean by read the "manual".
Visual C++ Express which I am using does not come with a manual.
But your are right that this brought the answer: I was using fgets() in manner in which it doesn't behave. I did not read the manual (In my case "The Complete Reference - C - Fourth Edition by Herbert Schildt") about fgets(). That would have told me that it does NOT replace the new line character as my beginner's book falsely suggested.
:-)

Thanks for the tip on perror()!
I build that one right into my program! :-)
It also helped me with debugging before I found the bug by reporting "Invalid Argument". Didn't help much, but DID point into the right general direction!

Quote:
Original post by ToohrVyk
Randomly trying to change your code to see if it works is possibly the worst thing that you could do

Actually, this was not entirely "random" as you might think: I know I'm not quite 100% comfortable with pointers, dereferencing and referencing them yet, so for a really quick test, it can't really hurt to see if you've messed up there (especially since I wasn't sure what fgets() exactly wants, a pointer, a constant pointer, a variable, a string literal, a dereferenced memory address, etc. ;-)

Anyhow, thanks, yes, I've: "called the wrong function"! :-)


Quote:
Original post by ShawnO
I'd suggest printing the contents of the two variables so you know exactly what you are passing to fopen(). I like to do this as part of my error handling.

Great advice!
Actually I was already doing that with a printf that was not quite as good as yours. Mine printed a message: "Could not open the file %s !" then came the file name (%s), then an exclamation mark.
Guess what: There was a little detail that kept on skipping my attention, but after rozz666's post, it REALLY got my attention: My exclamation mark was "magically" printed on a NEW LINE after my file name.

I'll update my file name reporting printf to your better version which also includes the file mode in one sweep set!

Thanks ALL!
You're the best helpers a newbie could wish for! [inlove]

Regards,
Mark

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement