C++ File I/O copying data from one file to other ...

So what I want to do is there is some data in one of the files called data.txt. The file has lines separated by periods . What I want to do is read the data from the data.txt file and store in another file Line by Line that means in this fashion
Line 1 : some text some text some
Line 2 : some text some text some

A single line could be either 75 characters long or until a period (.) is reached .
Content of the data.txt file
The default behaviour of ifstream type stream (upon opening files) allows users to read contents from the file. if the file mnode is ios::in only then readin is performed on a text file and if the file mode also includes ios::binary along with ios::in then, reading is performed in binary mode. No tranformation of characters takes place in binary mode whereas specific treanformations take place in text mode.

I wrote this
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <iostream>
#include <fstream>


using namespace std;

int main()
{

    ifstream fin;
    fin.open("data.txt",ios::in);

    ofstream fout;
    fout.open("new.txt",ios::out);
    char ch;
    char line[75];
    int i = 1;

    while(fin.get(ch)){
        fin.get(line,75,'.');
        fout<<"Line "<<i<<" : "<<line<<endl;
        i++;


    }
    fin.close();
    cout<<"done"<<endl;

    return 0;
}


The new file is called new.txt
Heres the output

1
2
3
4
5
6
7
8
Line 1 : he default behaviour of ifstream type stream (upon opening files) allows u
Line 2 : ers to read contents from the file
Line 3 :  if the file mnode is ios::in only then readin is performed on a text file
Line 4 : and if the file mode also includes ios::binary along with ios::in then, re
Line 5 : ding is performed in binary mode
Line 6 :  No tranformation of characters takes place in binary mode whereas specifi
Line 7 :  treanformations take place in text mode
Line 8 : 



As you can see the first characters are gone . I know thats because I use fin.get(ch) in the while condition, but I have no idea what else to do. Also I tried !fin.eof() as condition but this resulted into an infinite loop. What do I do to test if there is no more data left to be read in the file ?
you could use getline(std::istream&, char*).

1
2
3
4
5
6
while(fin.good())
{
    getline(fin, line);
    fout<<"Line "<<i<<": "<<line<<endl;
    ++i;
}
But then how do I test whether period comes first or 75 characters are read ? Cuz the line can either be 75 characters long or as long as a period is not encountered
1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>
#include <fstream>
#include <string>

int main()
{

    std::ifstream fin( "data.txt" ) ;
    std::ofstream fout( "new.txt" ) ;
    std::string line ;
    while( std::getline( fin, line, '.' ) ) fout << line << '\n' ;
}
If you just want to copy the file, open in binary mode and use read/write. Don't use text methods like getline(), the enod-of-line stuff varies between systems and is not always \n.
OK, back to your original question and what Pogrady was saying;

When you get input or output from a file there is an invisible variable that tells your program how far along it has gotten and where the next character to read is. Your while(fin.get(ch)) argument does test if there is something to be read, but it also tells that invisible variable that it has read another letter and must increase by one.

What pogrady's while(fin.good()) option does is it checks if there is still something to be read, but it doesn't increase that invisible variable. (It actually checks that the file is open, no errors have occurred, and the end of the file hasn't been reached)

So what you should do is replace the line "while(fin.get(ch))" with "while(fin.good())"

So do this and tell us how it works for you.

As a side note, if you want to get information about this invisible variable I told you about then look up seekp(Get the possition of the put pointer), seekg(Get the position of the get pointer), tellp(Set the position of the put pointer), and tellg(set the position of the get pointer).
Last edited on
fin.good() results in the output only upto Line 2 . (reference : first post )
I have provided the actual file and program, I will really appreciate if anyone checks it on their computer and helps me out .
I guess fin.good() stops working after the very first period there because the output is just

1
2
Line 1 : The default behaviour of ifstream type stream (upon opening files) allows 
Line 2 : users to read contents from the file


the first period comes after "the file"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <fstream>
#include <string>

int main()
{

    std::ifstream fin( "data.txt" ) ;
    std::ofstream fout( "new.txt" ) ;

    std::string line ;
    while( std::getline( fin, line, '.' ) )
    {
        constexpr std::size_t LINE_SZ = 75 ;

        while( line.size() > LINE_SZ ) // if longer than LINE_SZ, split it 
        {
            fout << line.substr( 0, LINE_SZ ) << '\n' ;
            line = line.substr(LINE_SZ) ;
        }

        fout << line << '\n' ;
    }
}
Topic archived. No new replies allowed.