CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 9 of 9

Thread: ios::trunc

  1. #1
    Join Date
    Aug 2009
    Posts
    68

    ios::trunc

    Hello,

    I am saving data to a file "myfile.dat". Every time I save new data, I want to eliminate the existing file and start a new file. From what I know, setting the ios::trunc flag should do this. However, I also want to create the file if no file exisits. So, the first the program is run, a new file "myfile.dat" is created, and every subsequent time, the data in this file should be eliminated and new data should be written.

    But just setting the ios::trunc flag does not seem to create a new file if the file does not exist. If I don't set the ios::trunc flag, then it does create a new file if one does not exist - but then the existing data in the file is not erased, and the new data is simply appendd to the end.

    Thanks.

    Here is my code, which writes 4 integars and then reads back the last integar in the file.

    Code:
            int length = sizeof(int);
    	ofstream out("myfile.dat", ios::out | ios::binary | ios::app | ios::trunc);
    	for (int x = 0; x < 5; x++)
    	{
    		out.write((char*)&x, sizeof(int));
    	}
    	out.close();
    
    	ifstream in("myfile.dat", ios::in | ios::binary);
    	if (!in.is_open())
    	{
    		cout << "Cannot open file." << endl;
    	}
    	int y;
    	in.seekg(-length, ios::end);
    	in.read((char*)&y, sizeof(int));
    	in.close();

  2. #2
    Join Date
    Jun 2010
    Location
    Germany
    Posts
    2,675

    Re: ios::trunc

    The behavior you describe isn't surprising at all: You explicitly tell the ofstream constructor to do that by passing the ios::app flag. Drop that and it should work.

    You then also can forego that creepy seekg() stunt shown in your code snippet when reading back your data.

    For more information see: http://www.cplusplus.com/reference/i...ream/ofstream/
    I was thrown out of college for cheating on the metaphysics exam; I looked into the soul of the boy sitting next to me.

    This is a snakeskin jacket! And for me it's a symbol of my individuality, and my belief... in personal freedom.

  3. #3
    Join Date
    Aug 2009
    Posts
    68

    Re: ios::trunc

    Hi,

    Thanks for your help. Losing the ios::app worked!

    However, I have also come across something else peculiar.

    If I use:
    Code:
    in.seekg(-(sizeof(int)), ios::end);
    instead of
    Code:
    int length = sizeof(int);
    in.seekg(-length, ios::end);
    then I cannot read back the data. The integar read back is something bizarre like -89980888. But I can see no difference really in how this code should compile. Any ideas?

    Thanks.

  4. #4
    Join Date
    Jun 2010
    Location
    Germany
    Posts
    2,675

    Re: ios::trunc

    The type of the first parameter of seekg() is streamoff. Its actual definition is implementation-dependent, but one thing that can be said about it is that it's a signed integral data type. The result type of sizeof, OTOH, is size_t which for sure is unsigned. I don't have the type conversion rules ready off-hand firmly enough to perfectly explain it, but I'm sure the explanation lies in there. Also, that problem itself is most likely implementation-dependent as well.

    But why do you need that piece of code at all anyway, now that writing to the file works properly?
    I was thrown out of college for cheating on the metaphysics exam; I looked into the soul of the boy sitting next to me.

    This is a snakeskin jacket! And for me it's a symbol of my individuality, and my belief... in personal freedom.

  5. #5
    Join Date
    Aug 2009
    Posts
    68

    Re: ios::trunc

    The reason I need that piece of code is because I need to read the last entry in the data file, before I read the rest of the file. When creating the file, I am adding numbers from an array to the file, but I don't know the length of the array because it is dynamically allocated, and its length can keep increasing. Therefore, I store the length of the array at the end of the file. When reading the file, I need to create the array of the specified length, so I read this last number back, create the array, and then read from the beginning of the file to fill the array.

  6. #6
    Join Date
    Jun 2010
    Location
    Germany
    Posts
    2,675

    Re: ios::trunc

    Looks like a perfect scenario to use a vector instead of a dynamically allocated array. The vector will grow as it needs to and you'll have the number of items it contains, returned by the vector's size() member, ready at hand to write it to the beginning of the file.

    You may even forego the item count in the file altogether, reading items from the file and push_back()-ing them to the vector, letting the vector resize on its own as needed, until you reach end-of-file. OTOH, reading the item count from the file, constructing the vector with the right number of items right from the start or pre-setting its size using the resize() member and then reading in all items at once in a single call to ifstream::read() is not only more efficient but also (IMO) more elegant.
    I was thrown out of college for cheating on the metaphysics exam; I looked into the soul of the boy sitting next to me.

    This is a snakeskin jacket! And for me it's a symbol of my individuality, and my belief... in personal freedom.

  7. #7
    Join Date
    Aug 2009
    Posts
    68

    Re: ios::trunc

    But is it possible to write the vector.size() value at the beginning of the file, after I've written the rest of the file?

  8. #8
    Join Date
    Jun 2010
    Location
    Germany
    Posts
    2,675

    Re: ios::trunc

    Sure. You'd just write a dummy value to the file (or seek sizeof(int) bytes forward), write the items, then seek back to the start of the file and write the item count. But you don't need to do that at all: The vector knows its own size at any point during execution of your code. No need to count anything!
    I was thrown out of college for cheating on the metaphysics exam; I looked into the soul of the boy sitting next to me.

    This is a snakeskin jacket! And for me it's a symbol of my individuality, and my belief... in personal freedom.

  9. #9
    Join Date
    Jul 2005
    Location
    Netherlands
    Posts
    2,042

    Re: ios::trunc

    Quote Originally Posted by karnavor View Post
    If I use:
    Code:
    in.seekg(-(sizeof(int)), ios::end);
    instead of
    Code:
    int length = sizeof(int);
    in.seekg(-length, ios::end);
    then I cannot read back the data. The integar read back is something bizarre like -89980888. But I can see no difference really in how this code should compile. Any ideas?
    The second is equivalent to
    Code:
    in.seekg(-static_cast<int>(sizeof(int)), ios::end);
    That's subtly different from your first code snippet, where the conversion is done after the negation.
    Cheers, D Drmmr

    Please put [code][/code] tags around your code to preserve indentation and make it more readable.

    As long as man ascribes to himself what is merely a posibility, he will not work for the attainment of it. - P. D. Ouspensky

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured