fopen with std::string

This is a discussion on fopen with std::string within the C++ Programming forums, part of the General Programming Boards category; Im trying to find a way to open several files with different names. My first problem creating this program is, ...

  1. #1
    Registered User
    Join Date
    Dec 2007
    Location
    France
    Posts
    749

    fopen with std::string

    Im trying to find a way to open several files with different names.
    My first problem creating this program is, how come that 'fopen()' which is a C++ function takes a C const char* argument?
    I thought we were supposed to use strings with C++.

    This is what i have so far, trying to figure out how to use strings.

    Code:
    #include <iostream>
    #include <string>
    using namespace std;
    
    
    int main ()
    {
      FILE * pFile;
      int i = 0;
      char ch[5] = {0,1,2,3,4};
      string str = "file.txt", str2;
      pFile = fopen (str,"w");
      while (i<5)
      {
        cout << "Enter word: "; cin >> str2;
        str.append(ch[i]);
        fprintf(pFile, str2);
        fclose (pFile);
        i++;
      }
      return 0;
    }
    Compiler MSVC++ 2010 with Code::Blocks.

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    21,310
    Quote Originally Posted by Ducky
    My first problem creating this program is, how come that 'fopen()' which is a C++ function takes a C const char* argument?
    I thought we were supposed to use strings with C++.
    Well, fopen() is actually inherited from the C standard library. That said, the C++ standard file streams also use a const char* parameter. The solution lies with the c_str() member function, e.g.,
    Code:
    pFile = fopen(str.c_str(), "w");
    By the way, it looks like you are closing the file in the loop. Also, you should #include <cstdio> for std::fopen().
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,641
    >> My first problem creating this program is, how come that 'fopen()' which is a C++ function takes a C const char* argument?

    fopen is a C function (but still valid for C++, of course). Incidentally, fstreams also take a const char*, which I've always found a bit odd. Anyway, you just need to invoke the std::string::c_str( ) function to get a pointer to the bytes.
    Code:
    if( numeric_limits< byte >::digits != bits_per_byte )
        error( "program requires bits_per_byte-bit bytes" );
    24bbs.cpp

  4. #4
    Registered User
    Join Date
    Jan 2005
    Posts
    7,317
    >> Incidentally, fstreams also take a const char*, which I've always found a bit odd.

    I agree. I'm pretty sure it's fixed in the next standard.

  5. #5
    Registered User
    Join Date
    Dec 2007
    Location
    France
    Posts
    749
    Thank you Laserlight and Sebastiani!

    "By the way, it looks like you are closing the file in the loop."
    Yes you are right thanks for recalling me but on second thoughts if i wanna open a new file every time i think i would have to close the precedent.

    I corrected the code. Now i just need to find out how to append a number each time to the filename.
    For a reason 'strcpy' wont accept the first arg.

    Code:
    #include <cstdio>
    #include <iostream>
    #include <string>
    using namespace std;
    
    
    int main ()
    {
     FILE * pFile;
      int i = 0;
      char ch[5] = {0,1,2,3,4};
      string filename = "file.txt", str2;
      pFile = fopen (filename.c_str(),"w");
      while (i<5)
      {
        cout << "Enter word: "; cin >> str2;
        strcpy(filename.c_str(), ch[i]);
        pFile = fopen (filename.c_str(),"w");
        fprintf(pFile, str2.c_str());
        fclose (pFile);
        i++;
      }
      return 0;
    }
    Compiler MSVC++ 2010 with Code::Blocks.

  6. #6
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    21,310
    Quote Originally Posted by Ducky
    Now i just need to find out how to append a number each time to the filename.
    You can use a stringstream. Here is the idea expressed as an example program:
    Code:
    #include <sstream>
    #include <string>
    #include <iostream>
    
    int main()
    {
        using namespace std;
    
        const string filename = "file";
        const string extension = ".txt";
        for (int i = 0; i < 5; ++i)
        {
            stringstream ss;
            ss << filename << i << extension;
            cout << ss.str() << endl;
        }
    }
    Speaking of which, is there a reason why you are not using std::fstream?
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  7. #7
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,641
    >> strcpy(filename.c_str(), ch[i]);

    >> For a reason 'strcpy' wont accept the first arg.

    You should never alter an std::string like that - any function that potentially transforms the size of the bytes (with respect to the null terminator) will lead to undefined behaviour. Furthermore, character transforms are safe, of course, unless the resulting character is itself the null terminator for that character type. The correct way would be simply:

    filename = ch[i];

    EDIT:
    I hadn't noticed the type of ch. Yes, use Laserlight's suggestion.
    Last edited by Sebastiani; 07-28-2009 at 02:49 PM.
    Code:
    if( numeric_limits< byte >::digits != bits_per_byte )
        error( "program requires bits_per_byte-bit bytes" );
    24bbs.cpp

  8. #8
    Registered User
    Join Date
    Dec 2007
    Location
    France
    Posts
    749
    Thank you very much again both of you!

    Of course, i forgot how easy it was to concatenate with strings, i just went complicating things again.

    "is there a reason why you are not using std::fstream?"

    No there isn't. Actually i just found this comparison between the two and it looks like std::fstream is faster.
    So im gonna use std::fstream instead. Thank you!

    http://social.msdn.microsoft.com/For...2-36248f86a8ce

    Ok, have a good day or night everybody, whatever is it over there, its already night here.
    Last edited by Ducky; 07-28-2009 at 03:39 PM.
    Compiler MSVC++ 2010 with Code::Blocks.

  9. #9
    C++11 User Tux0r's Avatar
    Join Date
    Nov 2008
    Location
    Sweden
    Posts
    135
    Quote Originally Posted by Ducky View Post
    Actually i just found this comparison between the two and it looks like std::fstream is faster.
    Read it again. The buffering is intensive.

  10. #10
    Registered User
    Join Date
    Dec 2007
    Location
    France
    Posts
    749
    "The buffering is intensive."

    Is it a bad thing?
    Compiler MSVC++ 2010 with Code::Blocks.

  11. #11
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,641
    >> Is it a bad thing?

    fstreams do have a bit more overhead, but you get what you pay for, and I think most would agree that the benefits outweigh the the drawbacks.
    Code:
    if( numeric_limits< byte >::digits != bits_per_byte )
        error( "program requires bits_per_byte-bit bytes" );
    24bbs.cpp

  12. #12
    C++11 User Tux0r's Avatar
    Join Date
    Nov 2008
    Location
    Sweden
    Posts
    135
    Just the fact that they use RAII is enough for me! And not to mention << and >>.

  13. #13
    Registered User
    Join Date
    Dec 2007
    Location
    France
    Posts
    749
    Ok, thanks Tux0r for your help!
    I dont understand right now what you're saying but i will look after it later when i'll have the time.

    For now i got Laserlight and Sebastiani telling me to prefer fstream so i rewrote the program with fstream.

    For a reason 'cout' accepts stringstream ss.str() but 'filestr.open()' won't.

    Code:
    #include <iostream>
    #include <string>
    #include <sstream>
    #include <fstream>
    
    using namespace std;
    
    
    int main ()
    {
        fstream filestr;
        filestr.open ("test.txt", fstream::in | fstream::out | fstream::app);
    
        const string filename  = "file";
        const string extension = ".txt";
        stringstream ss;
        string word;
    
        for (int i = 0; i < 5; ++i)
        {
            cout << "Enter word: "; cin >> word;
            ss << filename << i << extension;
            filestr.open (ss.str(), fstream::in | fstream::out | fstream::app);
            filestr << word.c_str() << endl;
            filestr.close();
        }
    
    
         return 0;
    }
    Compiler MSVC++ 2010 with Code::Blocks.

  14. #14
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,641
    Should be:

    Code:
    filestr.open (ss.str().c_str(), fstream::in | fstream::out | fstream::app);
    Code:
    if( numeric_limits< byte >::digits != bits_per_byte )
        error( "program requires bits_per_byte-bit bytes" );
    24bbs.cpp

  15. #15
    Registered User
    Join Date
    Dec 2007
    Location
    France
    Posts
    749
    Thank you!
    Compiler MSVC++ 2010 with Code::Blocks.

Page 1 of 3 123 LastLast
Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 13
    Last Post: 12-14-2007, 02:34 PM
  2. std::string: Has my compiler gone nuts??
    By Andruu75 in forum C++ Programming
    Replies: 9
    Last Post: 09-28-2007, 04:02 AM
  3. Debugging help
    By cuddlez.ini in forum C++ Programming
    Replies: 3
    Last Post: 10-24-2004, 07:08 PM
  4. DLL and std::string woes!
    By Magos in forum C++ Programming
    Replies: 7
    Last Post: 09-08-2004, 12:34 PM
  5. returning std::string
    By Unregistered in forum C++ Programming
    Replies: 3
    Last Post: 09-24-2001, 08:31 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21