Thread: Trouble with I/O

  1. #1
    Deprecated Dae's Avatar
    Join Date
    Oct 2004
    Location
    Canada
    Posts
    1,034

    Trouble with I/O

    Aight I'm still new to I/O.. so I was trying to do some things, and its not working out. The only thing I can assume is that it wont let you open close and then reopen the same file in one function, or else I'm missing something here.

    Heres my code, I'm trying to basicly take data from 'origFile' and move it to 'saveFile' and then move it back.

    Code:
    int Encrypt (char* inFileName)
    {
      ifstream origFile;
      ofstream saveFile;
    
      char outFileName[20] = "data.txt";
      char Byte;
    
      origFile.open (inFileName, ios::in | ios::binary);
      saveFile.open (outFileName, ios::out | ios::binary);
    
      while (origFile.get(Byte)) {
        saveFile.put (Byte);
      }
    
      origFile.close();
      saveFile.close();
      //these 4 lines dont make any difference.
      saveFile.open (inFileName, ios::out | ios::binary);
      origFile.open (outFileName, ios::in | ios::binary);
    
      while (saveFile.get(Byte)) { //error here
        origFile.put (Byte);
      }
    
    }
    I dont know if its necessary to close the files and reopen them.. I just assumed it would be in order for it to understand I want to move things from the in file to the out now. Either way it still gives me the error:

    Code:
    60 C:\Projects\inout_encryption.cpp `get' undeclared (first use this  function) 
    61 C:\Projects\inout_encryption.cpp `put' undeclared (first use this  function)
    It gave those errors the SECOND time I used them, not the first.. if I dont try and put the data back, no errors occur.

    Anyone mind helping? thanks
    Warning: Have doubt in anything I post.

    GCC 4.5, Boost 1.40, Code::Blocks 8.02, Ubuntu 9.10 010001000110000101100101

  2. #2
    VA National Guard The Brain's Avatar
    Join Date
    May 2004
    Location
    Manassas, VA USA
    Posts
    903
    try clearing your ifstream and ofstream objects before trying to perform an open( ) whenever you re-use them.

    Code:
    saveFile.clear();
    origFile.clear();
    saveFile.open (inFileName, ios::out | ios::binary);
    origFile.open (outFileName, ios::in | ios::binary);
    • "Problem Solving C++, The Object of Programming" -Walter Savitch
    • "Data Structures and Other Objects using C++" -Walter Savitch
    • "Assembly Language for Intel-Based Computers" -Kip Irvine
    • "Programming Windows, 5th edition" -Charles Petzold
    • "Visual C++ MFC Programming by Example" -John E. Swanke
    • "Network Programming Windows" -Jones/Ohlund
    • "Sams Teach Yourself Game Programming in 24 Hours" -Michael Morrison
    • "Mathmatics for 3D Game Programming & Computer Graphics" -Eric Lengyel

  3. #3
    Deprecated Dae's Avatar
    Join Date
    Oct 2004
    Location
    Canada
    Posts
    1,034
    No cigar.
    Warning: Have doubt in anything I post.

    GCC 4.5, Boost 1.40, Code::Blocks 8.02, Ubuntu 9.10 010001000110000101100101

  4. #4
    Banned
    Join Date
    Jun 2005
    Posts
    594
    Code:
    char letter;
    fstream filein, fileout;
    filein.open("myfile.txt", ios::in);
    fileout.open("myoutfile.txt", ios::out);
    if(!filein.fail() && !fileout.fail())
    {
         while(filein >> letter)
         {
              fileout << letter;
         }
    }
    filein.close();
    fileout.close();
    oh if your trying to do binary you could try
    Code:
    char ch;
    fstream in, out;
    in.open("test.in",ios::binary | ios::in);
    out.open("test.out",ios::binary | ios::out | ios::trunc);
    while(!in.fail())
    {
    	in.read(reinterpret_cast<char*>(&ch),sizeof(ch));
    	out.write(reinterpret_cast<char*>(&ch),sizeof(ch));
    }
    in.close();
    out.close();

    I didnt test it, jsut off the top of my head,
    but im pretty sure that will work.
    Last edited by ILoveVectors; 07-02-2005 at 10:32 PM.

  5. #5
    Deprecated Dae's Avatar
    Join Date
    Oct 2004
    Location
    Canada
    Posts
    1,034
    Thanks for trying guys,

    Its not working yet though.

    All three methods so far will work for the first "in" to "out" file, but will not work when trying to go from "out" to "in" file after the first.
    Warning: Have doubt in anything I post.

    GCC 4.5, Boost 1.40, Code::Blocks 8.02, Ubuntu 9.10 010001000110000101100101

  6. #6
    Sweet
    Join Date
    Aug 2002
    Location
    Tucson, Arizona
    Posts
    1,820
    This works for me.
    Code:
    #include <iostream>
    #include <fstream>
    
    void cleanUpFstream(std::fstream &cleanUp)
    {
        cleanUp.close();
        cleanUp.clear();
    }
    
    int main()
    {
        std::fstream origFile;
        std::fstream saveFile;
        
        char outFileName[] = "data.txt";
        char inFileName[] = "origData.txt";
        char byte;
        
        origFile.open(inFileName, std::ios::in | std::ios::binary);
        saveFile.open(outFileName, std::ios::out | std::ios::binary);
        
        while(origFile.get(byte))
        {
            saveFile.put(byte);
        }
        cleanUpFstream(origFile);
        cleanUpFstream(saveFile);
        
        origFile.open(outFileName, std::ios::out | std::ios::binary);
        saveFile.open(inFileName, std::ios::in | std::ios::binary);
        
        while(saveFile.get(byte))
        {
            origFile.put(byte);
        }
        return 0;
    }
    Output:
    Code:
    OrigData.txt before:
    Poop Pee
    data.txt before:
    *empty*
    OrigData.txt after:
    Poop Pee
    data.txt after:
    Poop Pee
    Woop?

  7. #7
    Deprecated Dae's Avatar
    Join Date
    Oct 2004
    Location
    Canada
    Posts
    1,034
    Yay, thanks!

    Using .clear() function worked, I just had the ios::in/out backwards on my files. Thanks for recommending fstream too, its much better to use for this.

    Yah its working with all the ways to I/O because of that clear() function.. now I got a program to encrypt/decrypt files, add it to a win32 API and thats cool
    Last edited by Dae; 07-03-2005 at 02:07 AM.
    Warning: Have doubt in anything I post.

    GCC 4.5, Boost 1.40, Code::Blocks 8.02, Ubuntu 9.10 010001000110000101100101

  8. #8
    Sweet
    Join Date
    Aug 2002
    Location
    Tucson, Arizona
    Posts
    1,820
    It's what I do and you're welcome.
    Woop?

  9. #9
    Deprecated Dae's Avatar
    Join Date
    Oct 2004
    Location
    Canada
    Posts
    1,034
    BTW, coincidently, while searching my harddrive for 'hl', I ran across some .txt talking about iostream binary, so I opened it. One part says:

    ... and, BTW, using 'std::istream::read()' and 'std:stream::write()'is almost certainly the *wrong* approach! These functions are an historical mistake which should have been corrected in the standard: It is my understanding that these methods were present in the IOStream version predating the rework from Jerry Schwartz and were left in to be compatible with the earlier stuff although they were not necessary: You could get binary I/O from the stream buffer level. The original IOStream library (maybe you remember using <stream.h>) did not have stream buffers and thus basic support for binary I/O was also present on the streams level.
    So what I/O should I use for binary. It says you can take it from the stream buffer level.. how do I do that? or if I use one of the other ways, which one?: read()/write(), the reinterpret_cast<char*> one, the >> << operator, or the get()/put()?
    Warning: Have doubt in anything I post.

    GCC 4.5, Boost 1.40, Code::Blocks 8.02, Ubuntu 9.10 010001000110000101100101

  10. #10
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >So what I/O should I use for binary.
    Don't think of the I/O operations as text and binary, think of them as formatted and unformatted. All of the operations will work regardless of the stream's orientation, so you can use << and >> with a binary stream if you want.

    >how do I do that?
    You call rdbuf() on the stream object to get a pointer to the streambuf object, then call sputn to write a sequence of characters. Here's an example using cout:
    Code:
    #include <iostream>
    #include <string>
    
    using namespace std;
    
    int main()
    {
      string s ( "This is a test" );
    
      cout.rdbuf()->sputn ( s.c_str(), s.size() );
    }
    >read()/write(), the reinterpret_cast<char*> one
    Generally to be avoided. Most people don't understand the pitfalls and end up writing code with undefined behavior.
    My best code is written with the delete key.

  11. #11
    Banned
    Join Date
    Jun 2005
    Posts
    594
    Quote Originally Posted by Prelude
    >>read()/write(), the reinterpret_cast<char*>
    one Generally to be avoided. Most people don't understand the
    pitfalls and end up writing code with undefined behavior.
    I had just came across that example somewhere and since at
    that time i hadnt learned about it i thought it was a good way,
    so ill remember this and use this from now on.

  12. #12
    Deprecated Dae's Avatar
    Join Date
    Oct 2004
    Location
    Canada
    Posts
    1,034
    Oh I see, thanks Prelude.

    I searched google for more information, another example is given here: http://www.cplusplus.com/ref/iostream/ios/rdbuf.html

    One person posted about binary I/O (http://lists.linux.org.au/archives/t.../msg00000.html) and one reply basicly says read()/write() is low/inefficient, and the other reply says using streambuf or read()/write() is fine (not sure if he thinks read()/write() are bad, but hes basicly just making a point) but not to use <</>> for binary I/O because those operators format the input (which you said) and thats not really necessary.

    So thats a no to read()/write() generally, and a no to <</>> for binary, so that leaves me with get()/put() or using streambuf with rdbuf()?

    Code:
    char Byte;
    
      fstream origFile ("something.txt", ios::in | ios::binary);
      fstream saveFile ("data.txt", ios::out | ios::binary);
    
      streambuf* rbuf, pbuf;
    
      rbuf = origFile.rdbuf();
      pbuf = saveFile.rdbuf();
    
      do {
        Byte = rbuf->sbumpc();
        pbuf->sputc(Byte);
      } while(rbuf->sgetc() != EOF);
    This compiles in Dev-Cpp, but of course VC++ has complaints:

    Code:
    C:\Projects\IO_test.cpp(20) : error C2248: 'basic_streambuf<char,struct std::char_traits<char> >::basic_streambuf<char,struct std::char_traits<char> >' : cannot access protected member declared in class 'std::basic_streambuf<char,struct std::char_tr
    aits<char> >'
            c:\program files\microsoft visual studio\vc98\include\streambuf(19) : see declaration of 'basic_streambuf<char,struct std::char_traits<char> >::basic_streambuf<char,struct std::char_traits<char> >'
    C:\Projects\IO_test.cpp(23) : error C2679: binary '=' : no operator defined which takes a right-hand operand of type 'class std::basic_filebuf<char,struct std::char_traits<char> > *' (or there is no acceptable conversion)
    C:\Projects\IO_test.cpp(27) : error C2819: type 'std::basic_streambuf<char,struct std::char_traits<char> >' does not have an overloaded member 'operator ->'
    C:\Projects\IO_test.cpp(27) : error C2227: left of '->sputc' must point to class/struct/union
    Warning: Have doubt in anything I post.

    GCC 4.5, Boost 1.40, Code::Blocks 8.02, Ubuntu 9.10 010001000110000101100101

  13. #13
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >streambuf* rbuf, pbuf;
    This is a classic example of why you shouldn't bind the asterisk of a pointer declaration to the type rather than the object. It's also a classic example of why you shouldn't declare more than one object on a single line. Why? Because pbuf isn't a pointer, but it should be:
    Code:
    streambuf *rbuf, *pbuf;
    Or:
    Code:
    streambuf* rbuf;
    streambuf* pbuf;
    >This compiles in Dev-Cpp, but of course VC++ has complaints
    Really. It seems like Dev-C++ is in the wrong this time, because the constructor for streambuf is protected.

    >and thats not really necessary
    Correct, but the same argument goes for string I/O as well as "binary" data, yet use of inserters and extractors is rampant for strings even when the stream is text oriented.

    >so that leaves me with get()/put() or using streambuf with rdbuf()?
    Let's just sidestep the entire issue, k?
    Code:
    // Copy the contents of in to out:
    out<< in.rdbuf();
    My best code is written with the delete key.

  14. #14
    Deprecated Dae's Avatar
    Join Date
    Oct 2004
    Location
    Canada
    Posts
    1,034
    Quote Originally Posted by Prelude
    >so that leaves me with get()/put() or using streambuf with rdbuf()?
    Let's just sidestep the entire issue, k?
    Code:
    // Copy the contents of in to out:
    out<< in.rdbuf();
    Alright cool, but even with streambuf's constructor being protected, its still better to use << for binary? Which I'm assuming formats also..

    Streambuf works well, and VC++ no longer complains now that you corrected my mistake.. but it is a lot more code than <<, but I could make a function (or operator overload) for it if its a better method for binary than inserters.
    Warning: Have doubt in anything I post.

    GCC 4.5, Boost 1.40, Code::Blocks 8.02, Ubuntu 9.10 010001000110000101100101

  15. #15
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >but even with streambuf's constructor being protected
    This has nothing to do with it. As long as you use streambuf pointers, you won't encounter this issue unless you have a need for the constructor in a custom stream of your own design. Since you aren't likely to need a custom stream for a while, you can forget about the constructor for streambuf and how it isn't public.

    >its still better to use << for binary?
    Okay, a streambuf only understands characters, so passing a streambuf to operator<< is identical in concept to passing a char to operator<<. Formatting is irrelevant. Passing a streambuf to operator<< is the most expedient (and usually the most efficient) way to copy the contents of an input stream to an output stream.
    My best code is written with the delete key.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Trouble with lesson 10 (File I/O)
    By sirconnorstack in forum C++ Programming
    Replies: 2
    Last Post: 05-28-2008, 05:20 PM
  2. trouble with file i/o program.
    By Pyroteh in forum C++ Programming
    Replies: 7
    Last Post: 01-09-2007, 10:29 PM
  3. Having file i/o trouble
    By LiKWiD in forum C++ Programming
    Replies: 1
    Last Post: 07-28-2004, 05:20 AM
  4. Replies: 4
    Last Post: 03-02-2003, 09:12 AM
  5. Overlapped I/O and Completion Port :: Winsock
    By kuphryn in forum Windows Programming
    Replies: 0
    Last Post: 10-30-2002, 05:14 PM