Jump to content
  • Advertisement
Sign in to follow this  
JamesCobras

Writing to the top of a text file preserving the rest of the doc.

This topic is 3348 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi guys, i have a load of HTML files that are lacking things like the <title> tags and stuff, and the files lose the changed stuff every time i re-publish, it's a problem with frontpage and templates. Anyway i thought hay, i can fix this, get a file read the first line for the file and the second line for the text that needs to go at the top of the file e.g. <title> title <title>. Now i planned it all out but i came to write a file with fstream (and it's associated classes). The only way i can open write and save (i have found) is with fstream::ate. I try to seek to the beggining of the doc, i've tried several times and realised that it only seeks within the current line. Also there is no function i have found that lets you seek lines. Apart from reading the whole file editing it in memory and re-writing the whole thing back to file (this seems a bit excessive), is there any way i can fill the empty line at the top of the file? I'm surprised i have encountered this problem, is there a libary that can be used, a portable lib would be best. JamesCobras

Share this post


Link to post
Share on other sites
Advertisement
Quote:
Original post by JamesCobras
Apart from reading the whole file editing it in memory and re-writing the whole thing back to file (this seems a bit excessive), is there any way i can fill the empty line at the top of the file?
Nope - that's the way it's always done. Files have no concept of lines, they're just a stream of bytes. Which is also why you can't seek to line X; only seek forwards X bytes.

Share this post


Link to post
Share on other sites
Right well if it's just 1 long line, why can't i seek to the first charater in the whole file.

e.g.

1------------ (10bytes)
------------- (10bytes)
------------- (10bytes)
------------- (10bytes)
2------------


I'm on line 2 how do i seek to point 1? It doesn't seem to want to.
I uderstand that to a computer it looks like one long line, but how do i seek to the start of the long line? e.g. back 40 bytes, it just doesn't seem to work?! I'd of thought it would.

JamesCobras

[Edited by - JamesCobras on July 23, 2009 6:30:10 AM]

Share this post


Link to post
Share on other sites
If you want to *overwrite* data at the start of a file, you can do that like this:


fstream file("filename.txt", ios::ate | ios::in | ios::out );

file.seekp(0, ios::beg);
file << "Overwriting the first characters in file.";



However, if your first line is nothing but a new line (which is most likely) then you have to realize that to you'll merely overwrite that newline and then start overwriting the second line's data. The new line character(s) is/are nothing more than additional characters to the file stream. It doesn't understand the difference between one line and the text.

Share this post


Link to post
Share on other sites
Ah, lovely just what i was looking for.

But why wasn't the following code working like that:


#include <fstream>
using namespace std;

int main () {

fstream HTML;

HTML.open ("test.txt", fstream.out | fstream::ate);

// >> i/o operations here <<


HTML.seekg(0,ios_base::beg);
HTML.write("\nhello4\n",8);


HTML.close();

return 0;
}

Share this post


Link to post
Share on other sites
Err no it didn't work guys.

text file before:

asdf
a
sdg
asdfgs
df
gas
dg
adsfg sad
fg

fg sdffg h hfgv asghfv asmnhdfv sadfg
asdfg as
dg
sdf
h a
dfg
a
sdfgas
fg
adf
g
ad
g
adfg
ad
fhadfhasdfg
adfgh
adfh
asdf
g
adsfg
asdf
ga
sdfg a
fg
a
sd
fah
a
fg
a
fg
adfh




After:

hello




Code:

#include <fstream>
using namespace std;

int main () {

fstream HTML;

HTML.open ("test.txt", ios::out | ios::ate);

// >> i/o operations here <<


HTML.seekg(0,ios_base::beg);
HTML << "hello";


HTML.close();

return 0;
}





Wanted:
After:

hello
asdf
asd
fa
sg
as
dfg

rg
aserg





Hope that clears a load of stuff up and helps you help me.

JamesCobras

P.S. i think that the code i was using was synominous with the code you gave me (got same results)

Share this post


Link to post
Share on other sites
Read the entire file into memory. Replace the lines. Write the entire file back out.

This is the easiest way.

#include <string>
#include <vector>
#include <fstream>
#include <iterator>
#include <algorithm>

typedef std::vector<std::string> FileData;

FileData read(const std::string &filename)
{
FileData result;
std::ifstream in(filename.c_str());
std::string line;
while(std::getline(in, line))
{
result.push_back(line);
}
return result;
}

void write(const std::string &filename, const FileData &data)
{
std::ofstream out(filename.c_str());
std::copy(data.begin(), data.end(), std::ostream_iterator<std::string>(out, "\n"));
}

void go(const std::string &filename)
{
FileData data = read(filename);

// modify data

write(filename, data);
}


This gives you a nice line based view of the file in the vector.

Share this post


Link to post
Share on other sites
Your code is overwriting the entire file because you forgot to include ios::in in your opening flags.


HTML.open("test.txt", ios::in | ios::out | ios::ate);


However, you still do not appear to be listening to the more important information that others are giving you in this thread.

In a file, a newline is represented not by a long empty line of spaces ready for you to overwrite, but by a single newline character (or possibly a newline and a carriage return sequence on some systems).

So the following:



this is some
text






looks like this in terms of characters in the file (\n is a newline character):


\nthis is some\ntext


If I now overwrite from pos 0 with the word "hello", it becomes:


hello is some\ntext


which in an editor is shown as:


hello is some
text






Quote:
Original post by JamesCobras
Apart from reading the whole file editing it in memory and re-writing the whole thing back to file (this seems a bit excessive), is there any way i can fill the empty line at the top of the file?


There is no empty line at the top of the file. There is (maybe some spaces then) a newline character at the start of the file.

James - load the entire file into memory using an ios::in file stream, then close the stream, then reopen the file with an ios::out file stream, then write your custom header to this stream, then write the previously loaded input file to the stream (or even better use std::ifstream and std::ofstream then you can't accidentally muddle up your read/write operations on the wrong stream).

This is not excessive - this is how these things are done.

[EDIT] And while I was typing this, rip-off has provided the code to do just that.

Share this post


Link to post
Share on other sites
Oh, kk, yeah thanks guys yep missing that iso::in was the killer.
Wow, i thought because I was only outputing that it wasn't needed.

Also i quite like the array idea to get things sorted and exact.

Thanks Guys, your help is appreciated.

James

Share this post


Link to post
Share on other sites
Have your template in file: template.txt.
Let your real file be: real.html

sed '1r template.txt' < real.html > newReal.html


This will insert contents of template.txt after first line, producing newReal.html.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!