c++: ifstream open problem with passing a string for text file name

67,558

Solution 1

the standard streams doesn't accept a standard string, only c-string! So pass the string using c_str():

aStream.open(textFile.c_str());

Solution 2

Try this:

aStream.open(textFile.c_str()); //line 11

I think your code needs to take the internal C string to pass to the open() call. Note I'm not at a compiler right now, so can't double check this.

You may also want to check the signature of the this method:

vector<Data*> DataReader(string textFile);

Here, a complete copy of the vector will be taken when it's returned from the method, which could be computationally expensive. Note, it won't copy the Data objects, just the pointers, but with a lot of data might not be a good idea. Similarly with the string input.

Consider this instead:

void DataReader( const string& textFile, vector<Data*>& dataOut );

Solution 3

ifstream open takes a const char* pointer as parameter, use c_str() function of std::string to get this pointer. You can see the meaning of the parameters here

Share:
67,558

Related videos on Youtube

user200632
Author by

user200632

Updated on July 09, 2022

Comments

  • user200632
    user200632 almost 2 years

    i'm trying to pass a string from main to another function. this string is a name of text file that needs to be oepened. as far as i can see, i am passing the string alright, but when i try to use ifstream.open(textFileName), it doesn't quite work. but when i manually hardcode it as ifstream.open("foo.txt"), it works just fine. i would need to use this function several times so i would like to be able to pass in a string of text file name..

    here's my main

    #ifndef DATA_H
    #define DATA_H
    #include "Data.h"
    #endif
    
    #ifndef DATAREADER_H
    #define DATAREADER_H
    #include "DataReader.h"
    #endif
    
    using namespace std;
    
    int main()
    {
     vector<Data*> database = DataReader("foo.txt");
    
     return 0; 
    }
    

    header of DataReader

    #include <fstream>
    #include <iostream>
    #include <vector>
    #include <string>
    
    #ifndef DATA_H
    #define DATA_H
    #include "Data.h"
    #endif
    
    using namespace std;
    
    vector<Data*> DataReader(string textFile);
    

    and finally the DataReader.cpp

    #include "DataReader.h"
    
    using namespace std;
    
    vector<Data*> DataReader(string textFile)
    {
     ifstream aStream;     
     aStream.open(textFile); //line 11
    

    i looked up the ifstream.open() and it takes a string and a mode as parameters. not really sure what to do with the modes, but i tried them but they gave the same error message

    DataReader.cpp: In function 'std::vector<Data*, std::allocator<Data*> > DataReader(std::string)':
    DataReader.cpp:11: error: no matching function for call to 'std::basic_ifstream<char, std::char_traits<char> >::open(std::string&)'
    /usr/local/lib/gcc/sparc-sun-solaris2.9/4.0.3/../../../../include/c++/4.0.3/fstream:495: note: candidates are: void std::basic_ifstream<_CharT, _Traits>::open(const char*, std::_Ios_Openmode) [with _CharT = char, _Traits = std::char_traits<char>]
    

    thank you in advance for any input/suggestions.

    Dean

    • Rob Kennedy
      Rob Kennedy over 14 years
      You will find greater success in life if you put your include guards inside the headers they're meant to guard. Including a header should be as simple as a single #include line, not four lines to conditionally include it, where you're required to know the name of each header's guard symbol. The first two lines of each header will be #ifndef/#define and the last line will be #endif. You should be able to find examples of this in every header you ever see.
  • user200632
    user200632 over 14 years
    thank you very much!! i think i should've have looked at the arguments more closely .....
  • Exectron
    Exectron over 10 years
    I figured c_str() should work based on the compile error, but I'm kind of surprised that C++ has no option to pass in a std::string.
  • NDEthos
    NDEthos over 8 years
    you just have to give your compiler the flag to use c++11 and you can then pass a string.
  • R1S8K
    R1S8K almost 5 years
    @NDEthos How to give the compiler the flag?
  • jpmarinier
    jpmarinier almost 5 years
    @R1S8K this is compiler dependent, so you have to check your compiler documentation. For GCC/G++ and CLANG, the relevant option is -std=c++11 for just C++11, or -std=c++1y if you want also the features of more recent versions.
  • R1S8K
    R1S8K almost 5 years
    @jpmarinier Yep, I found that in compiler settings. Thanks for the reply.