Programming Forums
User Name Password Register
 

RSS Feed
FORUM INDEX | TODAY'S POSTS | UNANSWERED THREADS | ADVANCED SEARCH

Reply
 
Thread Tools Display Modes
Old Jun 22nd, 2006, 5:44 PM   #1
crawforddavid2006
Expert Programmer
 
crawforddavid2006's Avatar
 
Join Date: Apr 2005
Location: Not sure yet
Posts: 597
Rep Power: 0 crawforddavid2006 is an unknown quantity at this point
Send a message via AIM to crawforddavid2006 Send a message via MSN to crawforddavid2006
Storing Data

How do I store data to a text file in C++?
__________________
Quote:
Originally Posted by DaWei View Post
Well, it's better than Pen Islands url....;)

crawforddavid2006 is offline   Reply With Quote
Old Jun 22nd, 2006, 5:46 PM   #2
LOI Kratong
Professional Programmer
 
Join Date: May 2005
Location: Woo - Boot Sector!
Posts: 294
Rep Power: 4 LOI Kratong is on a distinguished road
try writing to it, then reading from it?
__________________
www.heldtogether.co.uk
LOI Kratong is offline   Reply With Quote
Old Jun 22nd, 2006, 5:58 PM   #3
crawforddavid2006
Expert Programmer
 
crawforddavid2006's Avatar
 
Join Date: Apr 2005
Location: Not sure yet
Posts: 597
Rep Power: 0 crawforddavid2006 is an unknown quantity at this point
Send a message via AIM to crawforddavid2006 Send a message via MSN to crawforddavid2006
What I wanted to do was take an input from the program and save it to a text file
__________________
Quote:
Originally Posted by DaWei View Post
Well, it's better than Pen Islands url....;)

crawforddavid2006 is offline   Reply With Quote
Old Jun 22nd, 2006, 7:30 PM   #4
Jimbo
Battle Programmer
 
Jimbo's Avatar
 
Join Date: Feb 2006
Location: Bellevue, WA, USA
Posts: 773
Rep Power: 3 Jimbo is on a distinguished road
look up how to use fstreams and operator overloading. You'll probably want to be overloading ostream& operator<< (ostream&, YourType&) and istream& operator>> (istream&, YourType&).
Jimbo is offline   Reply With Quote
Old Jun 23rd, 2006, 8:01 AM   #5
DaWei
Resident Grouch
 
DaWei's Avatar
 
Join Date: Jun 2005
Posts: 6,453
Rep Power: 10 DaWei is on a distinguished road
This is material to be put into a "Common Questions" thing I'm working on. It's rough, yet.

HOW TO OPEN AND USE A FILE

Methods for opening files for reading and writing might be classified as C++, C stream, and C low-level methods. There are numerous variations, particularly with C++ streams; this post can in no way be considered exhaustive. CHECK YOUR DOCUMENTATION.

A NOTE ABOUT MODE

Unix/Linux have only one mode for file operations: binary. Windows has a text mode which is, unfortunately, the default. In text mode, content beyond what you supply is written to the file; it is stripped when you read the file. This makes the use of random access (seek, tell, etc.), problematic. Even worse, a 'soft' EOF, a special character, is written. This indicator is NOT MOVED if you do an append, so appended data is not reachable unless you reset the EOF indication. Consequently, I recommend always using binary mode. With 'fopen,' you can specify a read or write or other mode as "rb", "wb", etc. Unix/Linux will accept and ignore the 'b', so you can use it portably. You can also set the default mode in Windows with the global variable, _fmode.

C++ USING FSTREAM

VC++ 6.0, Windows XP
Include iostream, fstream, and string for the following examples.

FSTREAM
OPENING FOR WRITE
   // Example variables
   string sFileName = "test.txt";
   string sContents = "File data\n";
   string sToken;
   char   lineBuffer [256];
   int    nCount = 0;

   // Construct an fstream object and attempt to open
   // for output
   fstream ooFile;
   ooFile.open (sFileName.c_str (), ios::binary | ios::out);

   // Test for success
   if (!ooFile.is_open ()) return badHappenstance ("Couldn't open file for writing");

   // Write example
   ooFile << sContents;

   // Test the write for success
   if (!ooFile.good ()) return badHappenstance ("Write failed");

   // Close the file.  Note that the file will be closed automatically when
   // the object is destroyed (goes out of scope).
   ooFile.close ();
OPENING FOR READ
   // Open it for input
   ooFile.open (sFileName.c_str (), ios::binary | ios::in);
   if (!ooFile.is_open ()) return badHappenstance ("Couldn't open file for reading");

   // Read tokens until end of file or error
   while (ooFile.good ())
   {
      ooFile >> sToken;
      cout << "Token " << ++nCount << ": ";
      if (sToken.size ()) cout << sToken; else cout << "(null token)";
      cout << endl;
   }
   // Check some status for grins
   if (ooFile.eof ()) cout << "Reached EOF" << endl;
   else if (ooFile.fail ()) return badHappenstance ("Read failed for some reason");

   // Alternatively, read entire line
   ooFile.getline (lineBuffer, sizeof (lineBuffer));

   // Always the status
   if (!(ooFile.good () || ooFile.eof ()))
      return badHappenstance ("Failure reading line");

   cout << "This is the line: " << lineBuffer << endl;
A SEEK EXAMPLE
   // Position to beginning after clearing EOF or fail bits
   ooFile.clear ();
   ooFile.seekg (0, ios::beg);
   if (!ooFile.good ()) return badHappenstance ("Seek failed");

   ooFile.close ();
Example output:
[quote]
Token 1: File
Token 2: data
Token 3: (null token)
Reached EOF
This is the line: File data
[quote]

C USING FOPEN

VC++ 6.0, Windows XP
Include stdio.h for this method.

OPENING FOR WRITE
   // Example variables
   FILE *ooFile;
   char  sFileName [] = "test.txt";
   char  sContents [] = "File data\n";
   char  sToken [32];
   char  lineBuffer [256];
   int   nCount = 0;
   int   status;

   // Attempt to open file for output
   ooFile = fopen (sFileName, "wb");

   // Test for success
   if (!ooFile) return badHappenstance ("Couldn't open file for writing");

   // Write the contents
   status = fputs (sContents, ooFile);

   // Test for success
   if (status == EOF) return badHappenstance ("Write failed");

   // Close the file
   fclose (ooFile);
OPENING FOR INPUT
   ooFile = fopen (sFileName, "rb");
   if (!ooFile) return badHappenstance ("Couldn't open file for reading");

   // Read tokens until end of file or error -- one method: fscanf
   // fscanf consumes whitespace, unlike some C++ methods
   // so there won't be a null token at the end.
   while (1)
   {
      if (fscanf (ooFile, "%s", sToken) != 1)
      {
         if (feof (ooFile)) 
         {
            printf ("Reached EOF\n");
            break;
         }
         else return badHappenstance ("Failed to read token");
      }
      printf ("Token %d: %s\n", ++nCount, sToken);
   }
// REPOSITIONING EXAMPLE

   rewind (ooFile);

   // Read a line all in one swell foop
   // We'll either fill the buffer or have a newline
   // at the end of the buffer, or both.  If you don't
   // want the newline:
   //
   //    index = strlen (lineBuffer) - 1;
   //    if (lineBuffer [index] == '\n')
   //        lineBuffer [index] = '\0';"
   //
   if (fgets (lineBuffer, sizeof (lineBuffer), ooFile) == NULL)
      // Always the status; EOF is okay, error is not
      if (ferror (ooFile)) return badHappenstance ("Failed to read line");

   printf ("This is the line: %s", lineBuffer);
   fclose (ooFile);
Example output:
Quote:
Token 1: File
Token 2: data
Reached EOF
This is the line: File data
C USING LOW LEVEL _open

As far as I'm concerned, low level file operations are only good for reading large amounts of binary data, and are not necessary for that. One is far better off using the higher level functions.

VC++ 6.0, Windows XP
Include stdio.h, io.h, fcntl.h, sys\stat.h, ctype.h, and string.h for the
following example.

OPENING FOR READ/WRITE
typedef int fileHandle;
extern int errno;

   // Example variables
   fileHandle ooFile;
   char  sFileName [] = "test.txt";
   char  sContents [] = "File data\n";
   char  sToken [32];
   char  sTrash [32];
   char  lineBuffer [256];
   int   nChars, nTokens;
   int   status;

   // Attempt to open file for input/output
   ooFile = _open ("test.txt", _O_CREAT | _O_RDWR | _O_TRUNC | _O_BINARY, _S_IWRITE);

   // Test for success
   if (ooFile == EOF) return badHappenstance (strerror (errno));
WRITING
   // Write the contents
   status = _write (ooFile, sContents, strlen (sContents));

   // Test for success
   if (status == EOF) return badHappenstance ("Write failed");
SEEK AND READ OPERATION -- Far more complex than higher level methods
   // Return to the beginning for input
   if (_lseek (ooFile, 0, SEEK_SET) == -1L)
      return badHappenstance ("Seek to beginning failed");

   // Read tokens until end of file or error
   nTokens = 0;
   while (1)
   {
      // Skip any whitespace
      while (status = _read (ooFile, sTrash, 1) == 1)
         if (!isspace (sTrash [0])) break;
      // Check for EOF or failure
      if (status < 0) return badHappenstance ("Failure to read data");
      else if (status == 0) break;
      sToken [0] = sTrash [0];
      for (nChars = 1; nChars < sizeof (sToken) - 1; nChars++)
      {
         status = _read (ooFile, &sToken [nChars], 1);
         // Check for EOF or failure
         if (status < 0) return badHappenstance ("Failure in reading data");
         else if ((status == 0) || (isspace (sToken [nChars])))
         {
            sToken [nChars] = '\0';
            break;
         }
      }
      // The token could be too long...
      if (nChars >= sizeof (sToken) - 1)
      {
         sTrash [0] = ' ';
         // Skip any remaining non-whitespace characters
         while (status = _read (ooFile, sTrash, 1) == 1)
            if (!isspace (sTrash [0])) break;
         // Check for EOF or failure
         if (status < 0) return badHappenstance ("Failure in reading data");
         else if (status == 0) break;
      }
      // Or we could have completed the token
      if (strlen (sToken) > 0) printf ("Token %d: %s\n", ++nTokens, sToken);
   }
   printf ("End of file\n");

   // Reposition to beginning
   if (_lseek (ooFile, 0, SEEK_SET) == -1L)
      return badHappenstance ("Seek to beginning failed");

   // Read one buffer's worth
   status = _read (ooFile, lineBuffer, sizeof (lineBuffer) - 1);
   if (status > 0) 
      lineBuffer [status] = '\0';

   printf ("This is the line: %s", lineBuffer);
   _close (ooFile);

   return 0;
}
Example output:
Quote:
Token 1: File
Token 2: data
End of file
This is the line: File data
__________________
Abstraction doesn't make it impossible to write bad code; it makes it possible to write superior code.
Contributor's Corner: Grumpy on C++ Exceptions DaWei on Pointers
DaWei is offline   Reply With Quote
Old Jun 24th, 2006, 4:31 AM   #6
Soulstorm
Hobbyist Programmer
 
Soulstorm's Avatar
 
Join Date: Jan 2006
Location: Menidi, Athens, Greece
Posts: 243
Rep Power: 4 Soulstorm is on a distinguished road
Dawei, I want to ask you something about this:
Quote:
Originally Posted by DaWei
Unix/Linux have only one mode for file operations: binary. Windows has a text mode which is, unfortunately, the default. In text mode, content beyond what you supply is written to the file; it is stripped when you read the file. This makes the use of random access (seek, tell, etc.), problematic. Even worse, a 'soft' EOF, a special character, is written. This indicator is NOT MOVED if you do an append, so appended data is not reachable unless you reset the EOF indication. Consequently, I recommend always using binary mode. With 'fopen,' you can specify a read or write or other mode as "rb", "wb", etc. Unix/Linux will accept and ignore the 'b', so you can use it portably. You can also set the default mode in Windows with the global variable, _fmode.
I am using OS X, which has an underlying Unix Kernel. But I think the default mode for file operations is "text". I concluded this, because with all the files that I create, I can read it with a plain text editor, but if I change my program to make binary operations, I cannot read the output file without having the plain text editor saying that it will have to convert it to plain text first in order to be read.

And now my question. I am concerned about the problems you mentioned with the plain text file operation mode. It seems I am using that, at the moment, and I hadn't noticed the problems you mentioned, because I wasn't able to test them extensively, nor have I needed to access randomly a file. Can you tell me what is stripped exactly?
__________________
Project::Soulstorm (personal homepage)
Soulstorm is offline   Reply With Quote
Old Jun 24th, 2006, 7:17 AM   #7
DaWei
Resident Grouch
 
DaWei's Avatar
 
Join Date: Jun 2005
Posts: 6,453
Rep Power: 10 DaWei is on a distinguished road
Many people have this "feeling" that text and binary mode files use different encoding. It isn't so; it's the same. An ASCII 'A" will be written as 0x41 in both modes. The fact that it's also the value 65 is immaterial. You just have to know what your file contains. It's why files have extensions and magic numbers and all that hooey.

You may note when you're building strings that you use a newline as an ending. Where, then, is the dreaded Windows line ending of \r\n? It's built in text mode (not that you couldn't build it yourself). On output (in text mode), Windows prepends \r to each \n. On input, it's stripped. The other operation is to add the soft EOF, 0x1A, ctrl-Z. That's it. Obviously, if you read a binary file (by which I mean one with all sorts of byte-values), you're going to see EOF a lot. This is a common problem for novices. "I only read a little of my data file, then it just stops!!!" Then there is the problem of appending to a file, as mentioned above. One has to choose the proper append mode. One would NEVER want to use text mode with files containing non-textual data.

The questions is: should one use binary mode with textual data? As I said, it doesn't affect the text, other than line endings and the EOF mark. The addition of material by the function means that you can't rely on the file having the length you expect. That's why seeks and tells are problematic.

I have no earthly idea why you are having a problem with OS X, because I'm not familiar with it. It has nothing to do with text/binary mode differences as they apply to Windows machines. The difference you will see because of that will be double-spaced lines or files with no line breaks, depending on which way the file was written and whether or not the reproducing program is relying on the \r\n. There are no differences in encoding methods which relate to the file mode. Encoding variations because of locale, unicode, ASCII, things like that, are another picture which has nada to do with the file mode.

Any documentation regarding file operations that is provided by Microsoft will tell you in detail about these things. Some here and some there, maybe, but you will find it all with little trouble. The PHP manual discusses it, also. You may independently verify this information for yourself.

NOTE TO MOD: The [ quote ] in the fourth box down, my original post, should be [ /quote ]. I garfled it up.
__________________
Abstraction doesn't make it impossible to write bad code; it makes it possible to write superior code.
Contributor's Corner: Grumpy on C++ Exceptions DaWei on Pointers

Last edited by DaWei; Jun 24th, 2006 at 7:33 AM.
DaWei is offline   Reply With Quote
Old Jun 24th, 2006, 9:06 AM   #8
free-zombie
Programmer
 
free-zombie's Avatar
 
Join Date: May 2006
Location: Bavaria, Germany
Posts: 50
Rep Power: 0 free-zombie is an unknown quantity at this point
Send a message via ICQ to free-zombie Send a message via MSN to free-zombie Send a message via Yahoo to free-zombie
Mac has traditionally used \r instead of \n - so maybe OSX has the distinction.
DaWei: you should mention somwhere to use namespace std for that code. apart from that, _open etc are not standard I believe - what's wrong with stdio.h functions like fopen ?
free-zombie is offline   Reply With Quote
Old Jun 24th, 2006, 9:17 AM   #9
DaWei
Resident Grouch
 
DaWei's Avatar
 
Join Date: Jun 2005
Posts: 6,453
Rep Power: 10 DaWei is on a distinguished road
Perhaps you should read the post as well as study your C.

What's wrong with fopen? Did you not read this part?
   // Attempt to open file for output
   ooFile = fopen (sFileName, "wb");

   // Test for success
   if (!ooFile) return badHappenstance ("Couldn't open file for writing");
   ...blah blah blah
Did you read the part about low-level operations (_open)? You don't believe they're standard? Did you notice the quote?
Quote:
C USING LOW LEVEL _open

As far as I'm concerned, low level file operations are only good for reading large amounts of binary data, and are not necessary for that. One is far better off using the higher level functions.
You would have me recommend "using namespace std;" when that's a Bad Idea in many instances? Since the code is represented by mere snippets, where would you have me put it? Should I expand a discussion on file operations to deal with namespaces, scope resolution, and whatever else?

If you find errors in the presentation, please tell me. If you have differing ideas about presenting information, please make a contribution.
__________________
Abstraction doesn't make it impossible to write bad code; it makes it possible to write superior code.
Contributor's Corner: Grumpy on C++ Exceptions DaWei on Pointers
DaWei is offline   Reply With Quote
Old Jun 24th, 2006, 9:44 AM   #10
Soulstorm
Hobbyist Programmer
 
Soulstorm's Avatar
 
Join Date: Jan 2006
Location: Menidi, Athens, Greece
Posts: 243
Rep Power: 4 Soulstorm is on a distinguished road
Quote:
have no earthly idea why you are having a problem with OS X, because I'm not familiar with it. It has nothing to do with text/binary mode differences as they apply to Windows machines.
I should be more clear: I said that "I cannot read the output file without having the plain text editor saying that it will have to convert it to plain text first in order to be read" to indicate that I am certain that the file that I try to read is in binary mode.

I have no problems with OS X input/output whatsoever. The only reason that I asked you these things was to make certain that I have understood everything right, and that I will not encounter any problem in the future, that's all.

Quote:
Originally Posted by free-zombie
Mac has traditionally used \r instead of \n - so maybe OSX has the distinction.
Can you please explain this to me? By saying "Mac", do you mean Mac systems in general? Do you mean OS 7, OS 9, OS X?
__________________
Project::Soulstorm (personal homepage)
Soulstorm is offline   Reply With Quote
Reply

Bookmarks

« Previous Thread in Forum | Next Thread in Forum »

Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump




DaniWeb IT Discussion Community
All times are GMT -5. The time now is 2:20 PM.

Powered by vBulletin® Version 3.7.0, Copyright ©2000 - 2009, Jelsoft Enterprises Ltd.
Copyright ©2007 DaniWeb® LLC