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);
'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 |
댓글