About read txt file in c++

Hello all, I have a text file which contains words and punctuations like. I tried to use read() to read all the characters in the text file all at one. But when I tried to check the number of characters in the file, it said that it's can only read some of the characters and when i print all the characters in another text file there are some characters that are not in the input file.

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
int main()
{
    char * buffer;
    ifstream fin;
    fin.open("input.txt");
    fin.seekg(0,fin.end);
    int length = fin.tellg();
    fin.seekg (0, fin.beg);

    cout<<"The file has "<<length<<" letters."<<endl;
    buffer = new char [length];
    fin.read(buffer,length);
    if (fin)
    cout<<"All characters have been read";
    else cout << "error: only " << fin.gcount() << " could be read";

    getch();
   
    fin.close();

    ofstream fout;
    fout.open("out.txt");
    fout<<buffer;
    fout.close();
    delete[] buffer;
    return 0;
  
}

I wonder if there're anything with my code. If not, is there anyway to eliminate the unwanted characters in the buffer?
Thank you very much
Last edited on

The stream requires a null terminator, you are reading in the files length of say 14, allocating memory for 14 characters but since the memory address after that will be garbage (and most likely not null) it will write random rubbish until it finds one.

You also don't have any error checking, what happens if your program cant find the input.txt

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47

#include <iostream>
#include <fstream>

using namespace std;

int main()
{
	char * buffer;
	ifstream fin;
	fin.open("input.txt");
	
	// have we opened the file?
	if (fin.fail())
		cout << "Unable to find datafile";
	else
	{	
		fin.seekg(0, fin.end);
		int length = fin.tellg();
		fin.seekg(0, fin.beg);

		cout << "The file has " << length << " letters." << endl;
		buffer = new char[length+1];  // add 1
		fin.read(buffer, length);
		*(buffer + length) = 0;  // null terminate buffer

		if (fin)
			cout << "All characters have been read";
		else 
			cout << "error: only " << fin.gcount() << " could be read";

		fin.close();

		// write it out
		ofstream fout;
		fout.open("out.txt");
		fout << buffer;
		fout.close();

		// free buffer
		delete[] buffer;

	}
	return 0;

}
The discrepancy is probably related to the number of lines in the text file. in text mode, some translation of the line-ending sequence (on windows "\r\n" to "\n") may take place. If the file contains ordinary text, this is probably not a reall problem.

One other comment. Line 23 fout<<buffer; looks risky. It is treating the buffer as a null-terminated character string, however there is no guarantee that there will actually be a null found. For safety, you should allocate the buffer with one extra byte. After the read at line 12, buffer[ fin.gcount()] should be set to zero.

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
int main()
{
    ifstream fin("input.txt");
    fin.seekg(0,fin.end);
    int length = fin.tellg();
    fin.seekg (0, fin.beg);

    cout << "The file has " << length << " letters." << endl;
    char * buffer = new char [length + 1]; // allow room for null terminator
    fin.read(buffer,length);
    buffer[fin.gcount()] = 0;              // store null terminator
    if (fin)
        cout << "All characters have been read";
    else 
        cout << "warning: only " << fin.gcount() << " were be read";
    fin.close();

    ofstream fout("out.txt");
    fout << buffer;
    fout.close();
    delete[] buffer;
    
    // check length of output
    ifstream test("out.txt");
    test.seekg(0,test.end);
    length = test.tellg();
    cout << "\nlength of output file: " << length << endl;
    
    return 0;
}
Line 23 works on a null-terminated string. You haven't added a null character to the end of the string.

But this will only work if your input file doesn't contain a null character. If it does contain a null character, then line 23 will write to that character only.

So you need to use write() instead.
fout.write(buffer, length);

As for the number of characters, try opening the file in binary mode. I *think* that in text mode, the only thing you can reliably use tellg()'s output for is as input to seekg():
fin.open("input.txt", ios_base::binary);

Topic archived. No new replies allowed.