1

Can anybody help me with this simple thing in file handling?

This is my code:

#include<iostream>
#include<fstream>
#include<string>
using namespace std;

int main()
{
    fstream f;
    f.open("input05.bin", ios_base::binary | ios_base::out);
    string str = "";
    cout << "Input text:"<<endl;
    while (1)
    {
        getline(cin, str);
        if (str == "end")
            break;
        else {
            f.write((char*)&str, sizeof(str));
        }
    }
    f.close();
    f.open("input05.bin", ios_base::in | ios_base::binary);
    while (!f.eof())
    {
        string st;
        f.read((char*)&st, sizeof(st));
        cout << st << endl;
    }
    f.close();
}

It is running successfully now. I want to format the output of the text file according to my way.

I have:

hi this is first program i writer this is an experiment

How can I make my output file look like the following:

hi this is first program

I writer this is an experiment

What should I do to format the output in that way?

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • 1
    You should `f.write` something that consist of a newline character. Are you familiar with what `"\n"` is? – Fureeish Apr 17 '21 at 09:32
  • @Fureeish Thank you.Do you mean that i shoud write f.write((char*)&"\n",sizeof("\n")) ? – Trọng Lê Apr 17 '21 at 09:39
  • That would work. However, question, what is a new line supposed to be in a binary file? Lines make of course perfect sense in something to be read by a human, like your typical ASCII file. But a binary file will appear like a heap of random special characters if opened in a text editor. And you might have new lines other than those you intentionally insert in your document, simply because a byte of some variable happens to carry the value that a new line has in ASCII. – Aziuth Apr 17 '21 at 09:43
  • 1
    Unless you like typing needless characters, `f.put('\n');` would seem easier. – WhozCraig Apr 17 '21 at 09:43
  • 1
    `f.write((char*)&str, sizeof(str)); ... f.read((char*)&st, sizeof(st));` is absolutely the wrong way to do file I/O on a `std::string`. And `f.write((char*)&"\n",sizeof("\n"))` is wrong, `(char*)&"\n"` can be just `"\n"`, but `sizeof("\n")` doesn't return what you think it does. And [`while (!f.eof())` is wrong](https://stackoverflow.com/questions/5605125/), too. – Remy Lebeau Apr 17 '21 at 09:50

1 Answers1

1

First of all,

string str;
....
f.write((char*)&str, sizeof(str));

is absolutely wrong as you cast a pointer to an object of type std::string to a pointer to a character, i.e. char*. Note that an std::string is an object having data members like the length of the string and a pointer to the memory where the string content is kept, but it is not a c-string of type char *. Further, sizeof(str) gives you the size of the "wrapper object" with the length member and the pointer, but it does not give you the length of the string.

So it should be something like this:

f.write(str.c_str(), str.length());

Another thing is the os-dependant handling of new line character. Depending on the operating system, a new line is represented either by 0x0d 0x0a or just by 0x0d. In memory, c++ treats a new line always as a single character '\n'(i.e. 0x0d). When writing to a file in text mode, c++ will expand an '\n' to 0x0d 0x0a or just keep it as 0x0d (depending on the platform). If you write to a file in binary mode, however, this replacement will not occur. So if you create a file in binary mode and insert only a 0x0d, then - depending on the platform - printing the file in the console will not result in a new line.

Try to write ...

f.write(str.c_str(), str.length());
f.put('\r');

such that it will work on your platform (and will not work on other platforms then).

That's why you should write in text mode if you want to write text.

Stephan Lechner
  • 34,891
  • 4
  • 35
  • 58