[SOLVED] Inserting a new line in a file

Whether you're a newbie or an experienced programmer, any questions, help, or just talk of any language will be welcomed here.

Moderator: Coders of Rage

Post Reply
User avatar
dandymcgee
ES Beta Backer
ES Beta Backer
Posts: 4709
Joined: Tue Apr 29, 2008 3:24 pm
Current Project: https://github.com/dbechrd/RicoTech
Favorite Gaming Platforms: NES, Sega Genesis, PS2, PC
Programming Language of Choice: C
Location: San Francisco
Contact:

[SOLVED] Inserting a new line in a file

Post by dandymcgee »

I'm trying to insert a new line of text at the beginning of a large file. I have two questions.

1) Why is my current method writing rubbish at the end (see below)?
2) Will this work on very large (>1MB) text files? If not, could you recommend another solution?

test.txt

Code: Select all

Test text file
Test text file
Test text file
main.cpp

Code: Select all

#include <fstream>
#include <sstream>

int main( int argc, char *argv[] )
{
	//String stream
	std::stringstream newTextStream;
	newTextStream << "New line of text!";

	//Open file
	std::fstream file;
	file.open( "test.txt" );

	if( !file.is_open() ){
		return 1;
	}

	//Get length of file
	file.seekg ( 0, std::ios::end );
	int length = file.tellg();
	file.seekg ( 0, std::ios::beg );

	//Temporarily store file contents
	char *tempFile = new char[length];
	file.read( tempFile, length );
	file.close();

	//Rewrite file
	file.clear();
	file.open( "test.txt", std::ios::out );

	if( !file.is_open() ){
		return 1;
	}

	file << newTextStream.str() << std::endl << tempFile << std::endl;
	file.close();
}
Resulting test.txt:

Code: Select all

New line of text!
Test text file
Test text file
Test text fileÍÍÍÍýýýý««««««««îþîþîþ
As always, thanks for reading!

[Unrelated request]
Perhaps syntax highlighted code tags could be considered as a forum update?
Last edited by dandymcgee on Fri May 21, 2010 12:15 pm, edited 1 time in total.
Falco Girgis wrote:It is imperative that I can broadcast my narcissistic commit strings to the Twitter! Tweet Tweet, bitches! :twisted:
User avatar
short
ES Beta Backer
ES Beta Backer
Posts: 548
Joined: Thu Apr 30, 2009 2:22 am
Current Project: c++, c
Favorite Gaming Platforms: SNES, PS2, SNES, SNES, PC NES
Programming Language of Choice: c, c++
Location: Oregon, US

Re: Inserting a new line in a file

Post by short »

First of all, I created a 12.1mb file and ran your code on it. It worked perfectly. There were no problems. It just added a newline to the end of the textfile which is weird, a few minutes and I should figure that out.
My github repository contains the project I am currently working on,
link: https://github.com/bjadamson
User avatar
GroundUpEngine
Chaos Rift Devotee
Chaos Rift Devotee
Posts: 835
Joined: Sun Nov 08, 2009 2:01 pm
Current Project: mixture
Favorite Gaming Platforms: PC
Programming Language of Choice: C++
Location: UK

Re: Inserting a new line in a file

Post by GroundUpEngine »

I checked this out too, your code does exactly what it's supposed to, I debugged it in VC.
-Your output file seems to be corrupt or something, very strange

-With your test.txt the output was ->

Code: Select all

New line of text!
Test text file
Test text file
Test text file

-I also tryed this code on a huge 100MB file of junk and it just added an endline
User avatar
short
ES Beta Backer
ES Beta Backer
Posts: 548
Joined: Thu Apr 30, 2009 2:22 am
Current Project: c++, c
Favorite Gaming Platforms: SNES, PS2, SNES, SNES, PC NES
Programming Language of Choice: c, c++
Location: Oregon, US

Re: Inserting a new line in a file

Post by short »

Code: Select all

	newTextStream << "New line of text!";

Code: Select all

file << newTextStream.str() << std::endl << tempFile << std::endl;
Try this:

Code: Select all

       newTextStream << "New line of text!\n";

Code: Select all

file << newTextStream.str()  << tempFile;
This will result in adding a line to the beginning of your file, without adding another line at the end of the file. Also it may remove the random characters being added to the end of your file. I can't reproduce the random characters being added to your text file, so try it and post back.
My github repository contains the project I am currently working on,
link: https://github.com/bjadamson
User avatar
xiphirx
Chaos Rift Junior
Chaos Rift Junior
Posts: 324
Joined: Mon Mar 22, 2010 3:15 pm
Current Project: ******** (Unkown for the time being)
Favorite Gaming Platforms: PC
Programming Language of Choice: C++
Contact:

Re: Inserting a new line in a file

Post by xiphirx »

do you have extra white space characters after those lines of text in test.txt?

Try cerr'ing the length that you get, and comparing it to manually getting the length. Your text editor is probably adding the rubbish.
StarCraft II Zerg Strategy, open to all levels of players!

Looking for paid work :< Contact me if you are interested in creating a website, need a web design, or anything else you think I'm capable of :)
User avatar
short
ES Beta Backer
ES Beta Backer
Posts: 548
Joined: Thu Apr 30, 2009 2:22 am
Current Project: c++, c
Favorite Gaming Platforms: SNES, PS2, SNES, SNES, PC NES
Programming Language of Choice: c, c++
Location: Oregon, US

Re: Inserting a new line in a file

Post by short »

xiphirx wrote:do you have extra white space characters after those lines of text in test.txt?

Try cerr'ing the length that you get, and comparing it to manually getting the length. Your text editor is probably adding the rubbish.
I tried it, and the length was exactly as it should be. If its not it is definitely his text editor.
My github repository contains the project I am currently working on,
link: https://github.com/bjadamson
User avatar
dandymcgee
ES Beta Backer
ES Beta Backer
Posts: 4709
Joined: Tue Apr 29, 2008 3:24 pm
Current Project: https://github.com/dbechrd/RicoTech
Favorite Gaming Platforms: NES, Sega Genesis, PS2, PC
Programming Language of Choice: C
Location: San Francisco
Contact:

Re: Inserting a new line in a file

Post by dandymcgee »

short wrote: Try this:

Code: Select all

       newTextStream << "New line of text!\n";

Code: Select all

file << newTextStream.str()  << tempFile;
This will result in adding a line to the beginning of your file, without adding another line at the end of the file. Also it may remove the random characters being added to the end of your file. I can't reproduce the random characters being added to your text file, so try it and post back.
Same output.
xiphirx wrote:do you have extra white space characters after those lines of text in test.txt?

Try cerr'ing the length that you get, and comparing it to manually getting the length. Your text editor is probably adding the rubbish.
There's no way it's my text editor, no functional text editor would add that much rubbish to a text file (even a MS product like Notepad which is what I'm using). If it was the text editor, wouldn't it make sense that I would see if it i closed the file and reopened it? I don't, not until I run the program on it.

And to your first question, there is no extra white space.

It has to be reading the junk memory past the end of the char* into the file, but I don't understand why.
Falco Girgis wrote:It is imperative that I can broadcast my narcissistic commit strings to the Twitter! Tweet Tweet, bitches! :twisted:
Scoody
Chaos Rift Cool Newbie
Chaos Rift Cool Newbie
Posts: 65
Joined: Fri Feb 06, 2009 2:07 pm

Re: Inserting a new line in a file

Post by Scoody »

I'm guessing it's because you're just handing it the char* array which doesn't have the \0 terminator since you've only read the amount of chars in the file and reads past the array until a \0 is encountered.
read wrote:Notice that this is an unformatted input function and what is extracted is not stored as a c-string format, therefore no ending null-character is appended at the end of the character sequence.
Use file.write(tempFile,length) or make sure you add that \0 yourself.
User avatar
dandymcgee
ES Beta Backer
ES Beta Backer
Posts: 4709
Joined: Tue Apr 29, 2008 3:24 pm
Current Project: https://github.com/dbechrd/RicoTech
Favorite Gaming Platforms: NES, Sega Genesis, PS2, PC
Programming Language of Choice: C
Location: San Francisco
Contact:

Re: Inserting a new line in a file

Post by dandymcgee »

Scoody wrote:I'm guessing it's because you're just handing it the char* array which doesn't have the \0 terminator since you've only read the amount of chars in the file and reads past the array until a \0 is encountered.
read wrote:Notice that this is an unformatted input function and what is extracted is not stored as a c-string format, therefore no ending null-character is appended at the end of the character sequence.
Use file.write(tempFile,length) or make sure you add that \0 yourself.
Thanks! This was part of the solution. I still had to account for length being reported longer than I expected.

Working solution:

Code: Select all

#include <fstream>
#include <sstream>
#include <iostream
int main( int argc, char *argv[] )
{
	//String stream
	std::stringstream newTextStream;
	newTextStream << "New line of text!\n";

	//Open file
	std::fstream file;
	file.open( "test.txt" );

	if( !file.is_open() ){
		return 1;
	}

	//Get length of file
	file.seekg ( 0, std::ios::end );
	int length = file.tellg();
	file.seekg ( 0, std::ios::beg );

	//Temporarily store file contents
	char *tempFile = new char[length];
	for( int i = 0; i < length; i++ ){
		tempFile[i] = '\0';
	}
	file.read( tempFile, length );
	file.close();

	//Rewrite file
	file.clear();
	file.open( "test.txt", std::ios::out );

	if( !file.is_open() ){
		return 1;
	}

	file << newTextStream.str();
	char *discard = strchr( tempFile, (int)'\0' );
	file.write( tempFile, discard-tempFile );
	file.close();
}
I have no idea why the original worked for other people.. but this should make it work universally. Thanks for your help all! ;)
Falco Girgis wrote:It is imperative that I can broadcast my narcissistic commit strings to the Twitter! Tweet Tweet, bitches! :twisted:
Scoody
Chaos Rift Cool Newbie
Chaos Rift Cool Newbie
Posts: 65
Joined: Fri Feb 06, 2009 2:07 pm

Re: [SOLVED] Inserting a new line in a file

Post by Scoody »

It worked for others because they were lucky that the '\0' was the first char after the array.

Instead of doing this:

Code: Select all

   for( int i = 0; i < length; i++ ){
      tempFile[i] = '\0';
   }
Use memset to fill large memory chunks with the same value:

Code: Select all

memset(tempFile,0,length);
You could try opening the file as binary and use file.write, that way you don't have to mess around with filling the array and strchr. Use newTextStream.str().c_str() (IIRC :)) to get a char* for your string for file.write.
User avatar
dandymcgee
ES Beta Backer
ES Beta Backer
Posts: 4709
Joined: Tue Apr 29, 2008 3:24 pm
Current Project: https://github.com/dbechrd/RicoTech
Favorite Gaming Platforms: NES, Sega Genesis, PS2, PC
Programming Language of Choice: C
Location: San Francisco
Contact:

Re: [SOLVED] Inserting a new line in a file

Post by dandymcgee »

Scoody wrote: You could try opening the file as binary and use file.write, that way you don't have to mess around with filling the array and strchr. Use newTextStream.str().c_str() (IIRC :)) to get a char* for your string for file.write.
I'm not sure I understand. I'm using strchr to discard trailing null characters from the c-string.
Falco Girgis wrote:It is imperative that I can broadcast my narcissistic commit strings to the Twitter! Tweet Tweet, bitches! :twisted:
User avatar
M_D_K
Chaos Rift Demigod
Chaos Rift Demigod
Posts: 1087
Joined: Tue Oct 28, 2008 10:33 am
Favorite Gaming Platforms: PC
Programming Language of Choice: C/++
Location: UK

Re: [SOLVED] Inserting a new line in a file

Post by M_D_K »

C strings are null terminated by design (so you know where a string stops), when writing them anywhere (stdout, file, whatever) the null is not written; it's just used so you can figure out how long a string is.

Considering that strlen is basically this:

Code: Select all

int strlen(const char *str)
{
    int i;
    for(i = 0; *(str+i) != 0; i++)
        ;
    return i;
}
that garbage you get is probably cause of a lack of \0 at the end of a string (it can't tell where it ends).
Gyro Sheen wrote:you pour their inventory onto my life
IRC wrote: <sparda> The routine had a stack overflow, sorry.
<sparda> Apparently the stack was full of shit.
User avatar
dandymcgee
ES Beta Backer
ES Beta Backer
Posts: 4709
Joined: Tue Apr 29, 2008 3:24 pm
Current Project: https://github.com/dbechrd/RicoTech
Favorite Gaming Platforms: NES, Sega Genesis, PS2, PC
Programming Language of Choice: C
Location: San Francisco
Contact:

Re: [SOLVED] Inserting a new line in a file

Post by dandymcgee »

M_D_K wrote: that garbage you get is probably cause of a lack of \0 at the end of a string (it can't tell where it ends).
You still don't understand. I'm not getting any garbage anymore.

I'm filling char *tempFile with 0's;
Getting the file length (which is always larger than the actual amount of text);
Reading the file into tempFile (which leaves the extra space at the end of tempFile filled with the 0's I initially wrote);
Discarding the extra 0's;
Writing the contents of tempFile to the new file.

The only problem that remains is the fact that length is always incorrect in the positive. Since this causes no loss in functionality at all, I've elected to simply discard extra characters. If you see a better solution to this minor issue, feel free to enlighten me. ;)
Falco Girgis wrote:It is imperative that I can broadcast my narcissistic commit strings to the Twitter! Tweet Tweet, bitches! :twisted:
Post Reply