Trying to write a simple program that will read data but keep stumbling upon the fact that I kinda can't limit the amount that is read.
I have simple student.dat file which is filled ATM with nothing else but simple string "somethinginside", without quotes.
When I do this on each cout it outputs whole file plus several weird chars.

#include <iostream>
#include <fstream>

struct students
{
  char name[7];
  char lastname[15];
};

int main()
{
   int input(0); //for pause later
   students data;
   std::fstream dat ("student.dat", std::ios::in | std::ios::binary); //opens file for read
   dat.read ((char *) &data, sizeof(data)); //should read data
   std::cout << "name " << data.name << std::endl; //outputs more than it should
   std::cout << "lastname " << data.lastname << std::endl; //outputs more than it should
   dat.close(); // closes
   std::cin >> input; //pause to see output
   return true;
}

If I try adding this one after reading

std::fstream dt ("something.dat",std::ios::out | std::ios::binary);
dt.write (data.name, 10);
dt.close();

it will output "somethingi", while I'm pretty sure, I hope, that I defined it's length in structure and when reading how much to read.

I get same even if I try reading it with

dat.read (data.name, sizeof(data.name));

I'd be grateful for any helpful advice :)

Edited 6 Years Ago by ranko_6: n/a

Most likely your strings aren't being terminated with '\0'. What does the file look like?

Simple new text file, rename to student.dat, edit with notepad++, wrote "somethinginside", without quotes and that's it.

Though, I got an impression that it should just read block with size that is specified, not more, regardless of how string ends.

Only other option that I stumbled upon is to read data using get, though then I end up reading studet.name and student.lastname instead of just student.

So the problem is something of a misunderstanding of C-style strings. I'd recommend not using read and write (in general, actually, because they're only safe for POD types) and read each data member individually:

//dat.read ((char *) &data, sizeof(data)); //should read data
dat.get(data.name, sizeof data.name);
dat.get(data.lastname, sizeof data.lastname);
This question has already been answered. Start a new discussion instead.