Read line after line but from the eof.

G

Ground21

Hello.
How could I read the whole text file line after line from the end of
file? (I want to ~copy~ file)

I want to copy file in this way:

file 1:

a
b
c


file 2:

c
b
a
 
R

Rolf Magnus

Ground21 said:
Hello.
How could I read the whole text file line after line from the end of
file? (I want to ~copy~ file)

I want to copy file in this way:

file 1:

a
b
c


file 2:

c
b
a

The easiest way would be to read all the lines into something like an
std::vector<std::string> >, then write the new file iterating backwards
through the vector. As long as you don't have huge files, this should work
ok.
 
G

Ground21

The easiest way would be to read all the lines into something like an
std::vector<std::string> >, then write the new file iterating backwards
through the vector. As long as you don't have huge files, this should work
ok.

I think I wrote bad example:

Once more:

file1:

text1
text2
text3
abctest

file2:

abctest
text3
text2
text1
 
R

Rolf Magnus

Ground21 said:
I think I wrote bad example:

I did understand your posting anyway.
Once more:

file1:

text1
text2
text3
abctest

file2:

abctest
text3
text2
text1

Yup. What you should do is read the file line by line and put each line as a
separate string into a vector. So later you have a vector of lines. Then
you can iterate through that vector backwards and write the strings out
again.
 
O

Ondra Holub

Rolf Magnus napsal:
I did understand your posting anyway.


Yup. What you should do is read the file line by line and put each line as a
separate string into a vector. So later you have a vector of lines. Then
you can iterate through that vector backwards and write the strings out
again.

I would recommend std::list instead of std::vector, because list can be
simplier (== more effectively) extended in length.
 
R

red floyd

Ondra said:
Rolf Magnus napsal:

I would recommend std::list instead of std::vector, because list can be
simplier (== more effectively) extended in length.

I used deque.

I tried to be real clever, with reverse_copy on an istream_iterator, and
an ostream_iterator, but reverse_copy requires Bidirectional Iterators. :(
 
G

Ground21

Rolf Magnus napisał(a):
Yup. What you should do is read the file line by line and put each line as a
separate string into a vector. So later you have a vector of lines. Then
you can iterate through that vector backwards and write the strings out
again.

can You tell me what's wrong with this code?:
(I want to save lines from file 'file' to vectors, and then, write them
into "tmp.txt"). I got wrong output "tmp.log"... I think that is problem
with char*...

#include <vector.h>
vector <char*> tab(10);

tmp=fopen("tmp.txt","w");
fseek(file, 0L, SEEK_SET);
for(int i=0; i<lines; i++)
{
fgets(tab,256,file);
}
for(int i=lines; i>0; i--)
{
fputs(tab,tmp);
}
 
R

red floyd

Ground21 said:
Rolf Magnus napisał(a):
Yup. What you should do is read the file line by line and put each
line as a
separate string into a vector. So later you have a vector of lines. Then
you can iterate through that vector backwards and write the strings out
again.

can You tell me what's wrong with this code?:
(I want to save lines from file 'file' to vectors, and then, write them
into "tmp.txt"). I got wrong output "tmp.log"... I think that is problem
with char*...

#include <vector.h>
vector <char*> tab(10);

tmp=fopen("tmp.txt","w");
fseek(file, 0L, SEEK_SET);
for(int i=0; i<lines; i++)
{
fgets(tab,256,file);
}
for(int i=lines; i>0; i--)
{
fputs(tab,tmp);
}



Lets see...

1. What is "lines"?
2. What happens if there are more than 10 lines in a file?
3. What happens if a line is bigger than 256?
4. Why are you using arrays and C-style I/O?
5. What is <vector.h>? The C++ header is <vector>
6. Every entry in your vector is identical, since you're storing the
same address over and over.

And that's just off the top of my head.
 
G

Ground21

red floyd napisał(a):
1. What is "lines"?
int lines=0;
fseek(fileh,0L,SEEK_SET);
while(feof(fileh)==0) if(fgetc(fileh)=='\n') linies++;

lines - number of lines in my text file.
2. What happens if there are more than 10 lines in a file?

I read in wikibooks, that value of size will automaticlly increase if
necessary...

3. What happens if a line is bigger than 256?

I know, that it can be done better using something like strlen to check
line lenght, but for me, 256 is OK.
4. Why are you using arrays and C-style I/O?
5. What is <vector.h>? The C++ header is <vector>

in c++ builder 6 it works the same for said:
6. Every entry in your vector is identical, since you're storing the
same address over and over.


I though, that I take first line to tab[0], second line to tab[1]...
 
R

r

Ground21 said:
can You tell me what's wrong with this code?:
(I want to save lines from file 'file' to vectors, and then, write them
into "tmp.txt"). I got wrong output "tmp.log"... I think that is problem
with char*...

#include <vector.h>
vector <char*> tab(10);

tmp=fopen("tmp.txt","w");
fseek(file, 0L, SEEK_SET);
for(int i=0; i<lines; i++)
{
fgets(tab,256,file);
}
for(int i=lines; i>0; i--)
{
fputs(tab,tmp);
}


It's a bad mix of C and C++, besides the "Access violation".

// reading a file line by line
std::ifstream ifs ("tmp.txt");
std::string line;
std::vector<std::string> lines;
while (getline (ifs, line)) {
lines.push_back(line);
}

Is this already in the C++ FAQ?
 
R

Rolf Magnus

Ground21 said:
red floyd napisał(a):

int lines=0;
fseek(fileh,0L,SEEK_SET);
while(feof(fileh)==0) if(fgetc(fileh)=='\n') linies++;

lines - number of lines in my text file.


I read in wikibooks, that value of size will automaticlly increase if
necessary...

Yes, if you use the push_back member function.
I know, that it can be done better using something like strlen to check
line lenght, but for me, 256 is OK.

It would be better as well as easier to use std::string instead of raw char
arrays and pointers.
in c++ builder 6 it works the same for <vector> and <vector.h>...

otherwise your said:
6. Every entry in your vector is identical, since you're storing the
same address over and over.


I though, that I take first line to tab[0], second line to tab[1]...

You could try something based on this (untested):

#include <istream>
#include <ostream>
#include <string>
#include <vector>

void reverse_copy_file(std::istream& infile, std::eek:stream& outfile)
{
typedef std::vector<std::string> > vec_type;
vec_type text;

std::string line;
while (std::getline(infile, line))
text.push_back(line);

vec_type::const_reverse_iterator it = text.rbegin(), end = text.rend();
for (; it != end; ++it)
outfile << line << '\n';
}
 
G

Ground21

r said:
// reading a file line by line
std::ifstream ifs ("tmp.txt");
std::string line;
std::vector<std::string> lines;
while (getline (ifs, line)) {
lines.push_back(line);
}

Is this already in the C++ FAQ?

[C++ Error] zapis.cpp(136): E2285 Could not find a match for
'getline<_CharT,_Traits,_Alloc>(FILE *,string)'
 
R

red floyd

Ground21 said:
r said:
// reading a file line by line
std::ifstream ifs ("tmp.txt");
std::string line;
std::vector<std::string> lines;
while (getline (ifs, line)) {
lines.push_back(line);
}

Is this already in the C++ FAQ?

[C++ Error] zapis.cpp(136): E2285 Could not find a match for
'getline<_CharT,_Traits,_Alloc>(FILE *,string)'
That's because you didn't copy the whole example. He used an ifstream
for input, not a FILE*.

Use C++ style I/O if you're writing C++.
 
B

BobR

Ground21 wrote in message ...
Rolf Magnus napisał(a):

can You tell me what's wrong with this code?:
(I want to save lines from file 'file' to vectors, and then, write them
into "tmp.txt"). I got wrong output "tmp.log"... I think that is problem
with char*...
// >#include <vector.h>
#include said:
vector <char*> tab(10);
tmp=fopen("tmp.txt","w");
fseek(file, 0L, SEEK_SET);
for(int i=0; i<lines; i++){
fgets(tab,256,file);
}
for(int i=lines; i>0; i--){
fputs(tab,tmp);
}



#include <vector> // C++
#include <string>
#include <fstream>
#include <algorithm>

int main(){
std::ifstream copin( "ZZtest.txt" );
if( not copin.is_open() ){ throw "a fit";}

std::vector<std::string> TmpFile;
for( std::string line; std::getline( copin, line ); ){
TmpFile.push_back(line);
}
// copin.close();
std::reverse( TmpFile.begin(), TmpFile.end() ); // reverse it
std::eek:fstream out( "ZZtestR.txt" );
for( size_t i(0); i < TmpFile.size(); ++i ){
std::reverse( TmpFile.at(i).begin(), TmpFile.at(i).end());
out<< TmpFile.at( i ) <<std::endl;
}
// out.close();
} // main()
// ----------
// - contents "ZZtest.txt" -
Record 0
Record 1
Record 2
Record 3
Record 4
Record 5
Record 6

// - contents "ZZtestR.txt" -
6 droceR
5 droceR
4 droceR
3 droceR
2 droceR
1 droceR
0 droceR
 
T

Tobias Gneist

Ground21 said:
Hello.
How could I read the whole text file line after line from the end of
file? (I want to ~copy~ file)

I want to copy file in this way:

file 1:

a
b
c


file 2:

c
b
a

I think the most simple solution would use a stack an C++ I/O.

#include <iostream>
#include <fstream>
#include <stack>
#include <string>

using namespace std;

int main()
{
ifstream in("in.txt");
ofstream out("out.txt");
stack<string> ss;

string s;
in >> s;
while (!in.eof()) {
ss.push(s);
in >> s;
}
while (!ss.empty()) {
out << ss.top() << endl;
ss.pop();
}
return 0;
}
 
R

Rolf Magnus

Tobias said:
I think the most simple solution would use a stack an C++ I/O.

Hmm, right. A stack is actually a better choice than a vector.
#include <iostream>
#include <fstream>
#include <stack>
#include <string>

using namespace std;

int main()
{
ifstream in("in.txt");
ofstream out("out.txt");
stack<string> ss;

string s;
in >> s;
while (!in.eof()) {
ss.push(s);
in >> s;
}

Simpler and more correct than those last 5 lines would be:

while (in >> s)
ss.push(s);
while (!ss.empty()) {
out << ss.top() << endl;

No need to flush the stream after each line, so '\n' instead of endl is
sufficient.
 
G

gongzibi

I think the most simple solution would use a stack an C++ I/O.
#include <iostream>
#include <fstream>
#include <stack>
#include <string>

using namespace std;

int main()
{
ifstream in("in.txt");
ofstream out("out.txt");
stack<string> ss;

string s;
in >> s;
while (!in.eof()) {
ss.push(s);
in >> s;
}

If input likes:

test
122 345 345

output would be:

345
345
122
test

How about this

while (std::getline(in,s)) {
ss.push(s);
}

output would be:

122 345 345
test
 
G

Ground21

gongzibi napisał(a):
How about this

while (std::getline(in,s)) {
ss.push(s);
}

output would be:

122 345 345
test

ifstream in("log.txt");
ofstream out("out.txt");
stack<string> ss;

string s;
in >> s;

while (std::getline(in,s)) {
ss.push(s);
}
while (!ss.empty()) {
out << ss.top() << endl;
ss.pop(); }

this code works OK, but...

my log.txt file:

d/t: 2006-12-23/18:52:47 D:\c++\sem1\Project1.exe
d/t: 2006-12-23/18:52:49 D:\c++\sem1\Project1.exe
d/t: 2006-12-23/18:52:50 D:\c++\sem1\Project1.exe
d/t: 2006-12-23/18:52:52 D:\c++\sem1\Project1.exe

and output file:

d/t: 2006-12-23/18:52:52 D:\c++\sem1\Project1.exe
d/t: 2006-12-23/18:52:50 D:\c++\sem1\Project1.exe
d/t: 2006-12-23/18:52:49 D:\c++\sem1\Project1.exe
2006-12-23/18:52:47 D:\c++\sem1\Project1.exe

where is my "d/t: " ?
 
B

BobR

Ground21 wrote in message ...
ifstream in("log.txt");
ofstream out("out.txt");
stack<string> ss;

string s;
in >> s;

while (std::getline(in,s)) {
ss.push(s);
}
while (!ss.empty()) {
out << ss.top() << endl;
ss.pop(); }

this code works OK, but...

my log.txt file:

d/t: 2006-12-23/18:52:47 D:\c++\sem1\Project1.exe
d/t: 2006-12-23/18:52:49 D:\c++\sem1\Project1.exe
d/t: 2006-12-23/18:52:50 D:\c++\sem1\Project1.exe
d/t: 2006-12-23/18:52:52 D:\c++\sem1\Project1.exe

and output file:

d/t: 2006-12-23/18:52:52 D:\c++\sem1\Project1.exe
d/t: 2006-12-23/18:52:50 D:\c++\sem1\Project1.exe
d/t: 2006-12-23/18:52:49 D:\c++\sem1\Project1.exe
2006-12-23/18:52:47 D:\c++\sem1\Project1.exe

where is my "d/t: " ?

string s;
in >> s; // it's in this string you didn't save.
// delete that line.

while (std::getline(in,s)) { ss.push(s); }
 
G

Ground21

BobR napisał(a):
string s;
in >> s; // it's in this string you didn't save.
// delete that line.

while (std::getline(in,s)) { ss.push(s); }

works great!
thanks a lot!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,045
Latest member
DRCM

Latest Threads

Top