0

As in the title, when read a content of file i find it reads unknown symbols with the content.

The code:

char *buff = NULL;
size_t size = 0;    
ifstream file("c:\\file.txt", ios::out);

if(!file){
    cout << "File does not open." << endl;
}

file.seekg(0, file.end);
size = file.tellg();
file.seekg(0, file.beg);

buff = new char[size];
while(!file.eof()){
    file.read(buff, size);
}

cout << buff << endl;
delete[] buff;

The file content:

Hello world!. Thank you for help.

The result:

As you seen in the previous image, there are many unknowns symbols.
Why these symbols appear, what's wrong in my code ?

tshepang
  • 10,772
  • 21
  • 84
  • 127
Lion King
  • 28,712
  • 21
  • 69
  • 128
  • You should alloc size+1 for buff and set last character to '/0' - that will solve problem. You don't load unknown characters, you just print trash going after buffer. – Arkady Jul 07 '14 at 06:15
  • You should also null-terminate the string yourself. `read` reads bytes, not strings. – Adam Jul 07 '14 at 06:15
  • Even better would be using 'vector buffer' for that, avoiding allocation of memory by 'new' operator. – Arkady Jul 07 '14 at 06:16
  • I didn't get why you're passing `ios::out` to the input stream : `ifstream file("c:\\file.txt", ios::out);`. You can simply write `std::ifstream file("c:\\file.txt");`. Keep things simple! – Nawaz Jul 07 '14 at 06:17
  • If possible, please add a copy of at least some of the symbols into a code block in your question. What encoding is used with the file that you are reading? Additionally, you want to consider this, or other similar solutions: http://stackoverflow.com/questions/1138863/read-unicode-files – localhost Jul 07 '14 at 06:21
  • @Nawaz: Thanks for your tip. – Lion King Jul 07 '14 at 06:38
  • @Adam: Thanks, I have do `size+1` but I don't know how to set last character to '/0' . – Lion King Jul 07 '14 at 06:40
  • @LionKing No you don't. You have `buff = new char[size];` which, if you notice, is distinctly missing a `+1`. Once you fix that, add a `buff[size] = '\0';` after the `read()`. – Adam Jul 07 '14 at 06:47
  • @Adam: Good, works fine, but still appear the symbol `=`, for example: `Thank you for help.=` – Lion King Jul 07 '14 at 06:54

2 Answers2

3

Your char array is not null terminated, either create the array with space for one extra null character (and set it to '\0')

buff = new char[size + 1];
buff[size] = '\0';
// Or simply
buff = new char[size + 1]{};

or even better avoid using raw pointers wherever possible, especially for character arrays used as strings.

while(!file.eof()) is an antipattern, don't use it except in very specific cases.

std::ifstream file("file.txt");
std::string buff{ // Use regular brackets if not C++11
  std::istreambuf_iterator<char>(file),
  std::istreambuf_iterator<char>()
};
Community
  • 1
  • 1
user657267
  • 19,343
  • 5
  • 50
  • 73
1

You can only use operator<<(const char *) for C-style strings. You can't use it for arbitrary chunks of bytes. How would it know where to stop?

David Schwartz
  • 166,415
  • 16
  • 184
  • 259
  • OP doesn't know the difference. – Adam Jul 07 '14 at 06:47
  • @Adam Which is a good reason to avoid using C-style strings and related concepts (such as `char *`) in C++ when possible. – David Schwartz Jul 07 '14 at 06:48
  • I agree entirely. The trouble is that teaching materials for C++ are terrible. Newbies get introduced to this crap first and the proper C++ techniques are left for later. – Adam Jul 07 '14 at 06:58
  • What should happen is `std::copy` to `cout`. But who has the energy to properly explain those nuances to every fresh C++ kid struggling to make sense of what's been thrown at them? – Adam Jul 07 '14 at 07:03