Thread: No Matching Function Error When Opening File

  1. #1
    Registered User
    Join Date
    Jan 2008
    Posts
    19

    No Matching Function Error When Opening File

    I have a function in a .h file designed to save some information to a file, but I get this error:
    Code:
    error: no matching function for call to `std::basic_fstream<char, std::char_traits<char> >::basic_fstream(std::string&, std::_Ios_Openmode)'
    on this line:
    Code:
    fstream fbin(filename, ios::binary | ios::in | ios::out);
    This is the full code of the function as well as the includes:
    Code:
    #include <fstream>
    #include <iostream>
    
    using namespace std;
    
    ...
    
    void plant::writetofile(int pnum, string filename){
         fstream fbin(filename, ios::binary | ios::in | ios::out);
         if(!fbin){
                  cout << "Error opening fbin";
                  }
         
         int recsize = sizeof(int) + (sizeof(int) + sizeof(int) + sizeof(int))*2 + sizeof(string);
         fbin.seekp(pnum * recsize);
         
         fbin.write(reinterpret_cast<char*>(&name), sizeof(string));
         
         fbin.write(reinterpret_cast<char*>(waterd.getm()), sizeof(int));
         fbin.write(reinterpret_cast<char*>(waterd.getd()), sizeof(int));
         fbin.write(reinterpret_cast<char*>(waterd.gety()), sizeof(int));
         
         fbin.write(reinterpret_cast<char*>(aquired.getm()), sizeof(int));
         fbin.write(reinterpret_cast<char*>(aquired.getd()), sizeof(int));
         fbin.write(reinterpret_cast<char*>(aquired.gety()), sizeof(int));
         
         fbin.write(reinterpret_cast<char*>(&size), sizeof(int));
         
         fbin.close();
         return;
    }
    I have no idea why I am getting this error, since the line it is pointing to is fairly standard, I think.

    Any idea?

    Thanks!

  2. #2
    Registered User
    Join Date
    Mar 2007
    Posts
    416
    You need to designate it an ifstream or ofstream, meaning Input and/or Output file stream.

  3. #3
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    The problem is that due to an oversight (or some other technicality) standard C++ does not allow you to pass a string as the filename to an fstream. You have to call the c_str() function to pass a const char*:
    Code:
    fstream fbin(filename.c_str(), ...
    BTW, it looks like you're trying to write a string object out in binary. That won't work, because the string likely holds pointers to data outside the object (and for other reasons as well). Is there a reason you're using binary?

    >> You need to designate it an ifstream or ofstream, meaning Input and/or Output file stream.
    This is actually not true. An fstream will work fine.

  4. #4
    Registered User
    Join Date
    Mar 2007
    Posts
    416
    Quote Originally Posted by Daved View Post
    This is actually not true. An fstream will work fine.
    Really? I guess I learn something every day. I've tried fstream before also and got the same error. Changing it to if/ofstream fixed it and I never really thought twice about it. Thanks for clearing that up!

  5. #5
    Registered User
    Join Date
    Jan 2008
    Posts
    19
    Thanks for the help. I got the error I was getting fixed.

    Daved - The reason I am using binary rather than text is because, as I understand it, that is required for random access. If that is incorrect or if you know how I can get around the problem you described, that would be great. Of course, I cannot be sure that the problem you described is, well, a problem, since I have not yet gotten around to writing a way for the output file to be read. :-)

    Also, (sorry for all the questions) even after I got the errors I originally posted about fixed (thanks again), there were still some errors, which I narrowed down to the lines with this basic format:
    Code:
    fbin.write(reinterpret_cast<char*>(waterd.getd()), sizeof(int));
    I found that I can get around the errors by doing something like this:
    Code:
    int x = waterd.getd();
    fbin.write(reinterpret_cast<char*>(&x), sizeof(int));
    I am still curious why the first version did not work, though. Any explanation would be greatly appreciated.

    Thanks so much!

  6. #6
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    In the first example, you're trying to cast waterd.getd(); in the second, you are trying to cast the address of waterd.getd() (or more specifically, the address where the result of the function call is stored).

  7. #7
    Registered User
    Join Date
    Jan 2008
    Posts
    19
    tabstop - That makes sense, but then I should be able to add an & in front of waterd.getd() and it should work. Instead, when I do that I get this error:
    non-lvalue in unary '&'

    Thanks!

  8. #8
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    but then I should be able to add an & in front of waterd.getd()
    And what should be the result of it? I could not imagine
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  9. #9
    Registered User
    Join Date
    Mar 2007
    Posts
    416
    I think it is because there is no variable for the output of waterd.getd() to be assigned to, hence no memory location for it. Where the second has a location where the output was stored. I could be wrong, though.

  10. #10
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    No, there is memory for it. It would be a temporary.
    How could something be returned if it isn't stored somewhere? It wouldn't exist.
    The problem is a language-related one, not a machine-related one (it's a violation of how the language works).
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  11. #11
    Registered User
    Join Date
    Jan 2008
    Posts
    19
    OK. I wrote a read function. Everything works except for the name (the only string.) The name is just blank. I suspect this has to do with what Daved was talking about. Any idea how I can overcome this issue?

    Thanks!

  12. #12
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    I don't know exactly what you're referring to, but...
    Two things, then:

    fbin.write(reinterpret_cast<char*>(&name), sizeof(string));
    This is bad. Don't try to write a class in raw form. Instead just do fbin << name. The class will know how to store its data.
    And if you wondered about

    fbin.write(reinterpret_cast<char*>(waterd.getd()), sizeof(int));

    Then you already found a solution (use a temporary variable to hold the result, then write).
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  13. #13
    Registered User
    Join Date
    Jan 2008
    Posts
    19
    Quote Originally Posted by Elysia View Post
    fbin.write(reinterpret_cast<char*>(&name), sizeof(string));
    This is bad. Don't try to write a class in raw form. Instead just do fbin << name. The class will know how to store its data.
    I changed my program to use that way of doing things. I had no idea that was possible. (Could I just do that with my plant class?)

    Now the name has the correct name followed by a bunch of symbols and the integers are always the same....

    Any ideas?

    Thanks!

  14. #14
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by zephyrcat View Post
    I changed my program to use that way of doing things. I had no idea that was possible. (Could I just do that with my plant class?)
    Indeed you can, with proper operator overloading.
    If you've learned how to overload operators?
    There was a similar discussion on how to achieve this in http://cboard.cprogramming.com/showt...8&goto=newpost

    Code:
    Now the name has the correct name followed by a bunch of symbols and the integers are always the same....
    Do you need the file to be readable by humans?
    If not, then you should ignore them, because most likely the class stored some more data, such as the length of the string or some such.
    If you need to be able to read it without those symbols, then another, better way, might be to write the string itself (in const char* form), by doing fbin << name.c_str().
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  15. #15
    Registered User
    Join Date
    Jan 2008
    Posts
    19
    I don't need the file to be human readable, but I do need the program to be able to read it and display the information there in human readable form. Right now, when I use the readfromfile function that I wrote the program returns the name as the correct name followed by a bunch of random characters and the integers are always the same.

    I will include both functions, in case the problem is the reading function.

    Thanks!

    Code:
    void plant::readfromfile(int pnum, string filename){
         //cout << "Got to read from file function." << endl;
         fstream fbin(filename.c_str(), ios::binary | ios::in | ios::out);
         if(!fbin){
                  cout << "Error opening fbin";
                  }
         //cout << "Opened file." << endl;
         
         int recsize = sizeof(int) + (sizeof(int) + sizeof(int) + sizeof(int))*2 + sizeof(string);
         fbin.seekp(pnum * recsize);
         //cout << "Found place in file." << endl;
         
         fbin >> name;
         //fbin.read(reinterpret_cast<char*>(&name), sizeof(string)); //<-- old version
         //cout << "Read string from file." << endl;
         
         int m, d, y;
         
         fbin.read(reinterpret_cast<char*>(&m), sizeof(int));
         fbin.read(reinterpret_cast<char*>(&d), sizeof(int));
         fbin.read(reinterpret_cast<char*>(&y), sizeof(int));
         waterd.set(m,d,y);
         
         fbin.read(reinterpret_cast<char*>(&m), sizeof(int));
         fbin.read(reinterpret_cast<char*>(&d), sizeof(int));
         fbin.read(reinterpret_cast<char*>(&y), sizeof(int));
         aquired.set(m,d,y);
         
         //cout << "Read date info from file." << endl;
         
         fbin.read(reinterpret_cast<char*>(&size), sizeof(int));
         //cout << "Finished reading everything from file." << endl;
         
         fbin.close();
         //cout << "Leaving function." << endl;
         return;
    }
    Code:
    void plant::writetofile(int pnum, string filename){
         //cout << "Got to write to file function." << endl;
         fstream fbin(filename.c_str(), ios::binary | ios::in | ios::out);
         if(!fbin){
                  cout << "Error opening fbin";
                  }
         //cout << "Opened file." << endl;
         
         int recsize = sizeof(int) + (sizeof(int) + sizeof(int) + sizeof(int))*2 + sizeof(string);
         fbin.seekp(pnum * recsize);
         //cout << "Found place in file." << endl;
         
         fbin << name; //<-- new version
         //fbin.write(reinterpret_cast<char*>(&name), sizeof(string)); //<-- old version
         //cout << "Wrote string to file." << endl;
         
         int x;
         x=waterd.getm();
         fbin.write(reinterpret_cast<char*>(&x), sizeof(int));
         x=waterd.getd();
         fbin.write(reinterpret_cast<char*>(&x), sizeof(int));
         x=waterd.gety();
         fbin.write(reinterpret_cast<char*>(&x), sizeof(int));
         
         x=aquired.getm();
         fbin.write(reinterpret_cast<char*>(&x), sizeof(int));
         x=aquired.getd();
         fbin.write(reinterpret_cast<char*>(&x), sizeof(int));
         x=aquired.gety();
         fbin.write(reinterpret_cast<char*>(&x), sizeof(int));
         //cout << "Wrote date info to file." << endl;
         
         fbin.write(reinterpret_cast<char*>(&size), sizeof(int));
         //cout << "Finished writing everything to file" << endl;
         
         fbin.close();
         //cout << "Leaving function" << endl;
         return;
    }
    Last edited by zephyrcat; 07-14-2008 at 08:17 AM. Reason: Adding code

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Getting an error with OpenGL: collect2: ld returned 1 exit status
    By Lorgon Jortle in forum C++ Programming
    Replies: 6
    Last Post: 05-08-2009, 08:18 PM
  2. Compiling sample DarkGDK Program
    By Phyxashun in forum Game Programming
    Replies: 6
    Last Post: 01-27-2009, 03:07 AM
  3. Screwy Linker Error - VC2005
    By Tonto in forum C++ Programming
    Replies: 5
    Last Post: 06-19-2007, 02:39 PM
  4. <Gulp>
    By kryptkat in forum Windows Programming
    Replies: 7
    Last Post: 01-14-2006, 01:03 PM
  5. Unknown Memory Leak in Init() Function
    By CodeHacker in forum Windows Programming
    Replies: 3
    Last Post: 07-09-2004, 09:54 AM