본문 바로가기
College Study/C++ (ENG)

[C++] File I/O (ENG)

by 2den 2022. 1. 2.
728x90

 

File Stream

ifstream : input file

ofstream : output file

fstream : input and output file

 

We can use << , >> operator and a manipulator in a file stream.

 

// read only open
ifstream fin; // an object
fin.open("helloWorld.txt");

// write only open
ofstream fout;
fout.open("helloWorld.txt");

// read and write
fstream fs;
fs.open("helloWorld.txt");
 

 

 

open( )

Every stream has open( ) method.

fin.open("HelloWorld.txt", ios_base::in | ios_base::binary);
 

Mode Flags:

- namespace: ios_base

- Not all combinations are valid.

in, out, ate(at the end), app(append), trunc(open and discard), binary

 

// C - "r"
ios_base::in

// "w"
ios_base::out
ios_base::out | ios_base::trunc

// "a"
ios_base::out | ios_base::app

// "r+"
ios_base::in | ios_base::out

// "w+"
ios_base::in | ios_base::out | ios_base::trunc
 

 

 

close( )

Every stream has close( ) method.

ifstream fin;

// ...

fin.close();
 

 

 

is_open( )

checks whether the file is open.

fstream fs;
fs.open("HelloWorld.txt");

if (fs.is_open())
{
    // ...
}
 

 

Read a Character in a time

ifstream fin;
fin.open("HelloWorld.txt");

char character;
while (true)
{
    fin.get(character);
    if (fin.fail())
    {
        break;
    }
    cout << character;
}

fin.close();
 

 

get( ), getline( ), >> work the same with any stream (like cin, istringstream). => Abstraction

fin.get(character);

fin.getline(name, 20);    // read 20 characters from the file
getline(fin, line);       // read a line from the file

fin >> word;              // read a word from the file
 

 

 

Read a Line at a time

// not perfect
ifstream fin;
fin.open("HelloWorld.txt");

string line;
while (!fin.eof())
{
    getline(fin, line);
    cout << line << endl;
}

fin.close();
 

If the file is an empty file, you will get a blank line output.

 

 

 

Read a Word at a time

ifstream fin;
fin.open("HelloWorld.txt");

string name;
float balance;
while (!fin.eof())
{
    fin >> name >> balance;
    cout << name << ": $" << balance << endl;
}

fin.close();
 

 

 

case 1: one string and one number (good input)

 
Hwi 12000
Hwi : $12000

eofbit == true   failbit == false   fin points EOF.

 

 

 

case 2: number only (good input)

 
100 200 300

 

while (!fin.eof())
{
    fin >> number;
    cout << number << endl;
}

 

100
200
300

eofbit == true   failbit == false   fin points EOF.

 

 

 

case 3: numbers and newline(\n) (bad input)

 
100 200 300

 

while (!fin.eof())
{
    fin >> number;
    cout << number << endl;
}
 
100
200
300
300

eofbit == true   failbit == true   fin points EOF.

 

 

 

case 4: numbers with a wrong input (bad input)

 
100 C++ 300

 

while (!fin.eof())
{
    fin >> number;
    cout << number << endl;
}
 
100
100
100
100

infinite loop

eofbit == false   failbit == true   fin points "C".

 

 

 

Try 1: Output only what was read correctly

while (!fin.eof())
{
    fin >> number;

    if (!fin.fail())
    {
        cout << number << endl;
    }
}
 

When reading newline, the failbit becomes true so it checks the failbit. But it can not solve the problem of the case 4.

 

 

 

Try 2: Skip to next separator.

while (!fin.eof())
{
    fin >> number;

    if (!fin.fail())
    {
        fin.clear();
        fin.ignore(LLONG_MAX, ' ');
    }
    else
    {
        cout << number << endl;
    }
}
 

It ignores the input till it meets a space. But it has a problem when the input has taps(\t)and spaces( ) both.

 

 

 

Try 3: Read numbers only

ifstream fin;
fin.open("HelloWorld.txt");

int number;
string trash;
while (!fin.eof())
{
    fin >> number;

    if (fin.fail())
    {
        fin.clear();    // first
        fin >> trash;   // next
    }
    else
    {
        cout << number << endl;
    }
}
fin.close();
 

It works.

 

 

 

Best Practice

EOF treatment is tricky. Remember that input and output operations change the stream status bits. Incorrect handling of EOF can cause infinite repetition. When using clear( ), think twice.

 

Test the code.

 

test cases:

1. EOF after valid input

1 0 0 \n 2 0 0 EOF    

2. EOF after valid input and newline

1 0 0 \n 2 0 0 \n EOF  

3. EOF after invalid input

1 0 0 \n C + + EOF    

4. EOF after invalid input and newline

1 0 0 \n C + + \n EOF  

5. Black: Check tap and space

1 0 0   C + + \t ...  

6. Check both keyboard input and input redirection

100 200 300
cmd> number.exe < numberinput.txt
 

 

 

 

Write to file

ofstream fout;
fout.open("HelloWorld.txt");

string line;
getline(cin, line);
if (!cin.fail())
{
    fout << line << endl;
}

fin.close();
 

 

put( ), <<

fout.put(character);

fout << line << endl;
 

 

 

Read a Binary File

ifstream fin("studentRecords.dat", ios_base::in | ios_base::binary);

if (fin.is_open())
{
    Record record;
    fin.read((char*)&record, sizeof(Record));
}

fin.close();
 

ifstream::read( )

fin.read(&name, 20); // read(char*, streamsize)
 

 

 

Write to a Binary File

ofstream fout("studentRecords.dat", ios_base::out | ios_base::binary);

if (fout.is_open())
{
    char buffer[20] = "Pury Bab";
    fout.write(buffer, 20);
}

fout.close();
 

 

ofstream::write( )

fout.write(name, 20); // write(const char*, streamsize)
 

 

 

Seek in a File

fstream fs("helloWorld.dat", ios_base::in | ios_base::out | ios_base::binary);

if (fs.is_open())
{
    fs.seekp(20, ios_base::beg);
    if (!fs.fail())
    {
        // ...
    }
}

fs.close();
 

 

seek type

- absolute: usually used to return to the location you remember using tellp( ) / tellg( )

- relative: ios_base::beg, ios_base::cur, ios_base::end

 

read and change file write location

- tellp( ): optains the location of the write pointer

- seekp( )

fout.seekp(0); // absolute
fout.seekp(20, ios_base::cur); // relative
 

 

 

+

Don't use >> with getline( ).

cin >> number;
getline(cin, line);
 

rather:

cin >> number;
cin >> std::ws; // discard whitespace.
getline(cin, line);
 
 

 

728x90

'College Study > C++ (ENG)' 카테고리의 다른 글

[C++] Object-Oriented Programming : Overloading (ENG)  (0) 2022.01.02
[C++] Object-Oriented Programming : Class (ENG)  (0) 2022.01.02
[C++] File I/O (ENG)  (0) 2022.01.02
[C++] String (ENG)  (0) 2021.12.05
[C++] New Concepts (ENG)  (0) 2021.12.05

댓글