Open files without binary set

When I open the file(a php file that contains html and javascript) with "ios::binary" the output of the read() is correct.

But without "ios::binary" the output is equal to the entire file + 8-10 extra lines from the end of the file.

Why? (Usually when dealing with regular "text", ios::binary has not been necessary)
You can open the file in ios::binary mode or ios::text mode.

If you don't specify which, you get ios::text mode.

The actual data read from the file is the same in both - of course it is, there's only one file - but there are differences in how it's handled.

Does the file have 8-10 extra lines at the end?

When I open the file without binary, I dont get the same result(when I cout) as when I open it with binary.


Without binary:
The entire file + a repetition of the 10 last lines get printed out.

With binary
Exactly the entire file, nothing more

Show the code that is reading the file, please, @volang.
Sure.


ifstream fstream("index.php"); or ifstream fstream("index.php", ios::binary);
fstream.seekg (0, fstream.end);
int length = fstream.tellg();
fstream.seekg (0, fstream.beg);

char a[length];
fstream.read(a, length);



cout << a;
If opened as binary, there will be no conversion on input. If opened as text then there may be some conversions. For example, in Windows \r\n will be reduced to just \n. This may affect the "length" of your input.

However, you have other problems with your code.
- char a[length] is illegal in standard C++ (but allowed in the C99 version of C and in other languages with run-time allocatable arrays.)
- you are using cout << a; but your c-string isn't null-terminated.


even with : a[length] = '\0', I get repetition of some lines at the end. (When ios::binary is not set)

With ios::binary it's all good.

This is strange...
For example, in Windows \r\n will be reduced to just \n. This may affect the "length" of your input.


"int length" is equal to 2204(with and without mode: binary). If tellg() returns two chars for a newline even on a windows system, then that might be the problem. Because in that case i'm telling it to read in more than the "real" file length.

Last edited on
@volang, if you write a[length]='\0', then, besides the non-standard use of a VLA, you are writing beyond the end of an array.
The array works for now, but I changed it to length + 1.

But that's not what's causing the repetition. Could it have to do with my theory in my last post?

"int length" is equal to 2204(with and without mode: binary). If tellg() returns two chars for a newline even on a windows system, then that might be the problem. Because in that case i'm telling it to read in more than the "real" file length.
@volang,

What does the following give on your system?

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
#include <iostream>
#include <fstream>
using namespace std;

int main()
{
   char *a;
   ifstream f;
   int length, n;

   // Opened as text
   f.open( __FILE__, ios::ate );
   length = f.tellg();
   f.seekg( 0, f.beg );
   a = new char[length+1];   f.read( a, length );
   n = f.gcount();   a[n] = '\0';         // gcount gives actual number transferred
   cout << a;
   f.close();
   delete [] a;
   cout << "---\nText mode: reported file length: " << length << " bytes\n";
   cout <<      "           number transferred:   " << n      << " bytes\n";
   cout << "---\n\n";

   // Opened as binary
   f.open( __FILE__, ios::binary | ios::ate );
   length = f.tellg();
   f.seekg( 0, f.beg );
   a = new char[length+1];   f.read( a, length );
   n = f.gcount();   a[n] = '\0';                      
   cout << a;
   f.close();
   delete [] a;
   cout << "---\nBinary mode: reported file length: " << length << " bytes\n";
   cout <<      "             number transferred:   " << n      << " bytes\n";
   cout << "---\n\n";
}


On my (Windows) system it gives
(lines redacted)

---
Text mode: reported file length: 1074 bytes
           number transferred:   1038 bytes
---

(lines redacted)

---
Binary mode: reported file length: 1074 bytes
             number transferred:   1074 bytes
---


The deficit for text-mode transfer is the 36-lines-worth of \r that aren't transferred.
Last edited on
This is good. Nice explaining, i get it now.

I should use gcount instead of the length when I insert the terminating null. Length is not relevant here as I see now.
Topic archived. No new replies allowed.