Thread: file opening problem

  1. #1
    Registered User
    Join Date
    Oct 2007
    Posts
    118

    file opening problem

    Its been awhile im trying to refresh myself as i just started a c++ class and already i have a problem.

    Code:
    #include <stdio.h>
    
    FILE* open(const char filename[]);
    
    int main() {
        const char filename[11] = "prefix.dat";
        open(filename);
    }
    
    FILE* open(const char filename[]) {
          FILE* fp;
          printf(filename);
          fp = fopen(filename, "r");
          if (fp == NULL) {
             printf(" cannot open");
          }
          if (fp != NULL) {
             printf(" opened");
          } 
          fclose(fp);          
    }
    i have the prefix.dat in the same directory but it still says cannot open and also the function "FILE* open(const char filename[])" we are supposed to use and i was wondering can i use file* open to open the file or is that just a function like "int calculate(int number);"

  2. #2
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    I guess I'll just make a list.

    1. Don't make a function called "open" -- there is already a common function on many platforms with that name, and you are shadowing it.

    2. Using C stdio in a C++ program?

    3. Redundant if(fp != NULL) -- how could it be otherwise? Just say "else"

    4. You fclose() the handle immediately.

    5. If the fopen() failed, you will fclose() a NULL pointer, resulting in an explosion

    6. You never actually return the darn thing.

  3. #3
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    Why are you using C file I/O in a C++ program?
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  4. #4
    Registered User
    Join Date
    Oct 2007
    Posts
    118
    Quote Originally Posted by brewbuck View Post
    I guess I'll just make a list.

    1. Don't make a function called "open" -- there is already a common function on many platforms with that name, and you are shadowing it.

    2. Using C stdio in a C++ program?

    3. Redundant if(fp != NULL) -- how could it be otherwise? Just say "else"

    4. You fclose() the handle immediately.

    5. If the fopen() failed, you will fclose() a NULL pointer, resulting in an explosion

    6. You never actually return the darn thing.
    for 1. thats what the prof wants it named, i dont know why
    this is what he wants:
    Code:
    a function that receives the address of a C-style, null-terminated string containing the name of the file that holds the prefix table
    
     FILE* open(const char filename[]);
    
    This function opens the named file for read access and returns the address of the file pointer, if successful; NULL otherwise.
    3. i had "else" but it gave me the same output so i thought i should change it

  5. #5
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Do you actually have a file called "prefix.dat" in the same directory? If not, there's no way it will ever work.

  6. #6
    Registered User
    Join Date
    Oct 2007
    Posts
    118
    yes its in the same directory

  7. #7
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    Just because it is in the same directory doesn't mean it will work. Does it work if you use an absolute path?

  8. #8
    Registered User
    Join Date
    Oct 2007
    Posts
    118
    ^^ true because it opens now
    this works, but why?
    Code:
    const char filename[100] = "C:\\Documents and Settings\\matt\\Desktop\\a1\\prefix.dat";
    Last edited by bigmac(rexdale); 05-07-2008 at 02:59 PM.

  9. #9
    Registered User
    Join Date
    Aug 2004
    Location
    San Diego, CA
    Posts
    313
    Quote Originally Posted by bigmac(rexdale) View Post
    ^^ true because it opens now
    this works, but why?
    Code:
    const char filename[100] = "C:\\Documents and Settings\\matt\\Desktop\\a1\\prefix.dat";
    That's funny. I tried this code to see what happened, and if the executable and file were in the same directory, it worked just fine - but if I ran from the debugger (and had the file in the executable output directory), it wouldn't read it. Maybe that's part of your problem?

    I used this exact code:

    Code:
    #include <iostream>
    #include <cstdio>
    
    FILE* OpenFile(const char filename[]);
    
    int main()
    {
    	const char* filename = "prefix.dat";
    	FILE* fp;
        
    	if ((fp = OpenFile(filename)) != NULL)
    	{
    		std::cout << "File* Address: " << &fp << std::endl;
    	}
    	else
    	{
    		std::cout << "File* is NULL." << std::endl;
    	}
    
    	std::cin.get();
    }
    
    FILE* OpenFile(const char filename[])
    {
    	FILE* fp = fopen(filename, "r");
    
    	if (fp == NULL)
    	{
    		std::cout << "Cannot open file: " << filename << std::endl;
    		return(NULL);
    	}
    	else
    	{
    		std::cout << "Opened file: " << filename << std::endl;
    		return(fp);
    	}        
    }

  10. #10
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    Without an absolute path, the working directory is used. Sometimes that working directory is different than the directory that includes the executable (examples may include running from an IDE or running from a command prompt starting in a different directory).

    It's difficult to progammatically ensure the proper working directory in a platform independent way. You could just make it a prerequisite of the application that the file be in the same folder as the application, and then fix the way you are running your program to look in the right directory. For example, if you are running it from an IDE, the IDE will often have an option to set the default working directory. If you set that to the place you put your file it should work better with the relative path.

  11. #11
    Registered User
    Join Date
    Oct 2007
    Posts
    118
    Quote Originally Posted by Lithorien View Post
    That's funny. I tried this code to see what happened, and if the executable and file were in the same directory, it worked just fine - but if I ran from the debugger (and had the file in the executable output directory), it wouldn't read it. Maybe that's part of your problem?

    I used this exact code:

    Code:
    #include <iostream>
    #include <cstdio>
    
    FILE* OpenFile(const char filename[]);
    
    int main()
    {
    	const char* filename = "prefix.dat";
    	FILE* fp;
        
    	if ((fp = OpenFile(filename)) != NULL)
    	{
    		std::cout << "File* Address: " << &fp << std::endl;
    	}
    	else
    	{
    		std::cout << "File* is NULL." << std::endl;
    	}
    
    	std::cin.get();
    }
    
    FILE* OpenFile(const char filename[])
    {
    	FILE* fp = fopen(filename, "r");
    
    	if (fp == NULL)
    	{
    		std::cout << "Cannot open file: " << filename << std::endl;
    		return(NULL);
    	}
    	else
    	{
    		std::cout << "Opened file: " << filename << std::endl;
    		return(fp);
    	}        
    }
    ya its working now moved it to a next folder and its working good, but i was wondering can i use "FILE* open" to open the prefix.dat instead of using fp?
    nothing changed much:
    Code:
    #include <cstdio>
    
    FILE* open(const char filename[]);
    
    int main() {
        const char filename[100] = "prefix.dat";
        open(filename);
    }
    
    FILE* open(const char filename[]) {
          FILE* fp;
          char c[10];
          printf(filename);
          fp = fopen(filename, "r");
          if (fp == NULL) {
             printf(" cannot open");
          }
          else {
             printf(" opened");
             fscanf(fp, "&#37;s", c);
             printf("%s", c);
             fclose(fp);
          }        
    }
    and ya daved that was my problem command promt was working in the wrong directory

  12. #12
    Registered User
    Join Date
    Aug 2004
    Location
    San Diego, CA
    Posts
    313
    Quote Originally Posted by bigmac(rexdale) View Post
    i was wondering can i use "FILE* open" to open the prefix.dat instead of using fp?
    ...What? You're calling the function open() which returns a FILE*. fp is just a pointer to your FILE handle.

  13. #13
    Registered User
    Join Date
    Oct 2007
    Posts
    118
    Quote Originally Posted by Lithorien View Post
    ...What? You're calling the function open() which returns a FILE*. fp is just a pointer to your FILE handle.
    oh i see, so i should put return fp; to end it

  14. #14
    Registered User
    Join Date
    Aug 2004
    Location
    San Diego, CA
    Posts
    313
    Quote Originally Posted by bigmac(rexdale) View Post
    oh i see, so i should put return fp; to end it
    ...Yes, assuming you want to return the file pointer to the calling function. Which I think is what you need to do here. Right now with your code, all you're doing is returning null.

    Though if you're just closing the file anyway in your function, returning fp won't do a lot of good because it's a null pointer and if anyone tries to use it their application will likely crash.



    Edit: Let me explain, using your code.

    Code:
    #include <cstdio> // stdio.h, for file access.
    
    /* This is a function declaration. What this means is that this line
    declares a function (called open, that takes a const char[] called filename
    as an argument) that will be defined later in code. */
    FILE* open(const char filename[]);
    
    int main() {
        const char filename[100] = "prefix.dat"; // Why are you allocating a string like this? Try const char* filename.
        open(filename);
    }
    
    // Here's your function defination. This defines the function you declared before main().
    FILE* open(const char filename[]) {
          FILE* fp; // Create a FILE* called fp.
          char c[10];
          printf(filename);
          fp = fopen(filename, "r"); // Try to open the file, and return the file handle to your FILE* called fp.
          if (fp == NULL) { // If fopen() fails, fp is NULL...
             printf(" cannot open");
          }
          else { // ...else it succeeded and fp is valid.
             printf(" opened");
             fscanf(fp, "&#37;s", c);
             printf("%s", c);
    		 /* Why are you closing your file handle? This invalidates fp, and there's no reason
    		 to return a FILE* from open() if you do this. It will always be NULL. */
             fclose(fp);
    
    		 // You can return() fp here, or...
          }        
    
    	  // ...here, but ONLY if you keep fp valid and don't use fclose().
    }
    Last edited by Lithorien; 05-07-2008 at 03:37 PM.

  15. #15
    Registered User
    Join Date
    Oct 2007
    Posts
    118
    Quote Originally Posted by Lithorien View Post
    ...Yes, assuming you want to return the file pointer to the calling function. Which I think is what you need to do here. Right now with your code, all you're doing is returning null.

    Though if you're just closing the file anyway in your function, returning fp won't do a lot of good because it's a null pointer and if anyone tries to use it their application will likely crash.



    Edit: Let me explain, using your code.

    Code:
    #include <cstdio> // stdio.h, for file access.
    
    /* This is a function declaration. What this means is that this line
    declares a function (called open, that takes a const char[] called filename
    as an argument) that will be defined later in code. */
    FILE* open(const char filename[]);
    
    int main() {
        const char filename[100] = "prefix.dat"; // Why are you allocating a string like this? Try const char* filename.
        open(filename);
    }
    
    // Here's your function defination. This defines the function you declared before main().
    FILE* open(const char filename[]) {
          FILE* fp; // Create a FILE* called fp.
          char c[10];
          printf(filename);
          fp = fopen(filename, "r"); // Try to open the file, and return the file handle to your FILE* called fp.
          if (fp == NULL) { // If fopen() fails, fp is NULL...
             printf(" cannot open");
          }
          else { // ...else it succeeded and fp is valid.
             printf(" opened");
             fscanf(fp, "&#37;s", c);
             printf("%s", c);
    		 /* Why are you closing your file handle? This invalidates fp, and there's no reason
    		 to return a FILE* from open() if you do this. It will always be NULL. */
             fclose(fp);
    
    		 // You can return() fp here, or...
          }        
    
    	  // ...here, but ONLY if you keep fp valid and don't use fclose().
    }
    oh ok, so do i ever need to fclose then if i want to return fp?
    Last edited by bigmac(rexdale); 05-07-2008 at 03:47 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Formatting a text file...
    By dagorsul in forum C Programming
    Replies: 12
    Last Post: 05-02-2008, 03:53 AM
  2. Formatting the contents of a text file
    By dagorsul in forum C++ Programming
    Replies: 2
    Last Post: 04-29-2008, 12:36 PM
  3. C++ std routines
    By siavoshkc in forum C++ Programming
    Replies: 33
    Last Post: 07-28-2006, 12:13 AM
  4. Dikumud
    By maxorator in forum C++ Programming
    Replies: 1
    Last Post: 10-01-2005, 06:39 AM
  5. Unknown Memory Leak in Init() Function
    By CodeHacker in forum Windows Programming
    Replies: 3
    Last Post: 07-09-2004, 09:54 AM