《C++primer(제5판)》 학습의 길 - 제8장: IO 라이브러리
10020 단어 C++Primer
8.1 입출력 클래스
1.
istream(입력 흐름) 유형, 입력 작업 제공
ostream(출력 흐름) 형식, 출력 작업 제공
cin, 표준 입력에서 데이터를 읽는 istream 대상
cout,ostream 대상, 표준 출력에 데이터를 쓰기
cerr,ostream 대상, 보통 프로그램 오류 정보를 출력하는 데 사용되며, 표준 오류에 기록됩니다
>> 연산자, istream 대상에서 입력 데이터를 읽는 데 사용
<< 연산자, ostream 대상에게 출력 데이터를 쓰기
getline 함수, 주어진istream에서 한 줄의 데이터를 읽고 주어진string 대상에 저장합니다
2.
IO 형식은 세 개의 독립된 헤더 파일에서 정의됩니다: iostream은 읽기와 쓰기 제어 창의 형식을 정의하고 fstream은 이름이 붙은 파일의 형식을 정의하며 sstream이 정의한 형식은 메모리에 저장된string 대상을 읽기와 쓰기에 사용합니다.fstream과 sstream에서 정의된 모든 종류는 iostream 헤더 파일에서 정의된 관련 종류에서 파생됩니다.
3. 입출력 라이브러리 유형 및 헤더 파일
4. 입출력 라이브러리 조건 상태
strm::iostate // , iostream ,
strm::badbit // strm::iostate ,
strm::failbit // strm::iostate , IO
strm::eofbit // strm::iostate ,
s.eof() // s eofbit , true
s.fail() // s failbit , true
s.bad() // s badbit , true
s.good() // s , true
s.clear() // s
s.clear(flag) // s 。flag strm::iostate
s.setstate(flag) // s 。flag strm::iostate
s.rdstate() // s , strm::iostate
5.
버퍼 리셋을 초래하는 원인은 매우 많다. 1.프로그램이 정상적으로 끝났습니다.main 함수의return 작업의 일부분으로 버퍼 리셋이 실행되었습니다.2. 버퍼가 가득 차면 버퍼를 새로 고쳐야 새로운 데이터가 버퍼에 계속 쓸 수 있습니다.3. 우리는 endl과 같은 컨트롤 문자를 사용하여 버퍼를 현저하게 갱신할 수 있다.4. 매번 출력 작업이 끝난 후에 우리는 조작부호인 unitbuf로 흐름의 내부 상태를 설정하여 버퍼를 비울 수 있다.기본적으로,cerr에 대해 unitbuf를 설정하기 때문에,cerr에 쓴 내용은 즉시 갱신됩니다.5. 하나의 출력 흐름이 다른 흐름과 연결될 수 있습니다.이런 상황에서 설사가 연관된 흐름에 의해 연관된 흐름의 완충구가 갱신된다.
6. 출력 버퍼 새로 고침
endl 조종자, 줄 바꾸기를 출력하고 버퍼를 새로 고침하는 데 사용됩니다.flush 조종자, 흐름을 새로 고침하는 데 사용되지만 출력에 문자를 추가하지 않습니다.ends 조작부호, 이 조작부호는 버퍼에 빈 문자null를 삽입한 다음 새로 고칩니다.
7.
unitbuf 조종자, 이 조종자는 쓰기 작업이 끝날 때마다 흐름을 갱신합니다.nounitbuf 조종자는 흐름을 시스템이 관리하는 버퍼 리셋 방식으로 복구합니다.
8.2 파일 입출력
1. C++는 다음과 같은 몇 가지 클래스를 통해 파일의 입력 출력을 지원합니다: ofstream: 쓰기 (출력) 의 파일 클래스 (ostream에서 인용) ifstream: 읽기 (입력) 의 파일 클래스 (istream에서 인용) fstream: 동시에 읽기 및 쓰기 가능한 파일 클래스 (iostream에서 인용)
2. 파일 모드 in 파일 열기 읽기 동작out 파일 열기 쓰기 동작 app 쓰기 전에 파일 끝ate 파일을 찾은 후 파일 끝에trunc로 파일을 열 때 존재하는 파일 흐름 비우기 binary 바이너리 모드로 IO 작업
8.3 string 흐름
1. 표준 라이브러리는 세 가지 유형의 문자 직류를 정의했다.istringstream,istream에서 파생되어 읽기string 기능을 제공한다.ostringstream, ostream에서 파생되어 string을 쓰는 기능을 제공합니다.stringstream, iostream에서 파생되어 읽기 및 쓰기 기능을 제공합니다.
2.stringstream 특정 작업
sstream strm; strm은 연결되지 않은stringstream 대상입니다.sstream은 헤더 파일 sstream에 정의된 형식입니다
sstream strm(s); strm은 sstream 대상으로strings의 복사본을 저장합니다.이 구조 함수는explict입니다.
strm.str ()는strm에 저장된string의 복사본을 되돌려줍니다
strm.str (s) 는strings를strm에 복사합니다.void 반환
PS: 부분 연습 답안
연습8.1
istream& func(istream& is)
{
std::string sbuf;
while(is >> sbuf)
std::cout << sbuf << std::endl;
is.clear();
return is;
}
연습
#include <iostream>
using std::istream;
istream& func(istream& is)
{
std::string sbuf;
while(is >> sbuf)
std::cout << sbuf << std::endl;
is.clear();
return is;
}
int main()
{
istream& is = func(std::cin);
std::cout << is.rdstate() << std::endl;
return 0;
}
연습
#include <fstream>
#include <string>
#include <vector>
#include <iostream>
using std::vector;
using std::string;
using std::ifstream;
using std::cout;
using std::endl;
void ReadFileToVec(const string& fileName,vector<string>& vec)
{
ifstream ifs(fileName);
if(ifs)
{
string buf;
while(std::getline(ifs,buf))
vec.push_back(buf);
}
}
int main()
{
vector<string> vec;
ReadFileToVec("data.txt",vec);
for(const auto& str:vec)
cout << str << endl;
return 0;
}
연습 8.5
#include <fstream>
#include <string>
#include <vector>
#include <iostream>
using std::vector;
using std::string;
using std::ifstream;
using std::cout;
using std::endl;
void ReadFileToVec(const string& fileName,vector<string>& vec)
{
ifstream ifs(fileName);
if(ifs)
{
string buf;
while(ifs >> buf)
vec.push_back(buf);
}
}
int main()
{
vector<string> vec;
ReadFileToVec("data.txt",vec);
for(const auto& str:vec)
cout << str << endl;
return 0;
}
연습
<pre name="code" class="cpp">#include <fstream>
#include <iostream>
#include "ex7_26.h"
using std::ifstream;
using std::cout;
using std::endl;
using std::cerr;
int main(int argc, char** argv)
{
ifstream input(argv[1]);
Sales_data total;
if (read(input, total))
{
Sales_data trans;
while (read(input, trans))
{
if (total.isbn() == trans.isbn())
total.combine(trans);
else
{
print(cout, total) << endl;
total = trans;
}
}
print(cout, total) << endl;
}
else
{
cerr << "No data?!" << endl;
}
return 0;
}
练习8.7#include <fstream> #include <iostream> #include "ex7_26.h" using std::ifstream; using std::ofstream; using std::endl; using std::cerr; int main(int argc, char** argv) { ifstream input(argv[1]); ofstream output(argv[2]); Sales_data total; if (read(input, total)) { Sales_data trans; while (read(input, trans)) { if (total.isbn() == trans.isbn()) total.combine(trans); else { print(output, total) << endl; total = trans; } } print(output, total) << endl; } else { cerr << "No data?!" << endl; } return 0; }
연습#include <fstream> #include <iostream> #include "ex7_26.h" using std::ifstream; using std::ofstream; using std::endl; using std::cerr; int main(int argc, char** argv) { ifstream input(argv[1]); ofstream output(argv[2], ofstream::app); Sales_data total; if (read(input, total)) { Sales_data trans; while (read(input, trans)) { if (total.isbn() == trans.isbn()) total.combine(trans); else { print(output, total) << endl; total = trans; } } print(output, total) << endl; } else { cerr << "No data?!" << endl; } return 0; }
연습#include <iostream> #include <sstream> using std::istream; istream& func(istream& is) { std::string buf; while(is >> buf) std::cout << buf << std::endl; is.clear(); return is; } int main() { std::istringstream iss("hello word"); func(iss); return 0; }
연습#include <iostream> #include <fstream> #include <sstream> #include <vector> #include <string> using std::vector; using std::string; using std::ifstream; using std::istringstream; using std::cout; using std::endl; using std::cerr; int main() { ifstream ifs("data.txt"); if (!ifs) { cerr << "No data?" << endl; return -1; } vector<string> vecLine; string line; while (getline(ifs, line)) vecLine.push_back(line); for (auto& s : vecLine) { istringstream iss(s); string word; while (iss >> word) cout << word << endl; } return 0; }
연습#include <iostream> #include <sstream> #include <string> #include <vector> using std::vector; using std::string; using std::cin; using std::istringstream; struct PersonInfo { string name; vector<string> phones; }; int main() { string line, word; vector<PersonInfo> people; istringstream record; while (getline(cin, line)) { PersonInfo info; record.clear(); record.str(line); record >> info.name; while (record >> word) info.phones.push_back(word); people.push_back(info); } for (auto& p : people) { std::cout << p.name << " "; for (auto& s : p.phones) std::cout << s << " "; std::cout << std::endl; } return 0; }
연습#include <iostream> #include <sstream> #include <fstream> #include <string> #include <vector> using std::vector; using std::string; using std::cin; using std::istringstream; using std::ostringstream; using std::ifstream; using std::cerr; using std::cout; using std::endl; using std::isdigit; struct PersonInfo { string name; vector<string> phones; }; bool valid(const string& str) { return isdigit(str[0]); } string format(const string& str) { return str.substr(0, 3) + "-" + str.substr(3, 3) + "-" + str.substr(6); } int main() { ifstream ifs("data.txt"); if (!ifs) { cerr << "no phone numbers?" << endl; return -1; } string line, word; vector<PersonInfo> people; istringstream record; while (getline(ifs, line)) { PersonInfo info; record.clear(); record.str(line); record >> info.name; while (record >> word) info.phones.push_back(word); people.push_back(info); } for (const auto& entry : people) { ostringstream formatted, badNums; for (const auto& nums : entry.phones) if (!valid(nums)) badNums << " " << nums; else formatted << " " << format(nums); if (badNums.str().empty()) cout << entry.name << " " << formatted.str() << endl; else cerr << "input error: " << entry.name << " invalid number(s) " << badNums.str() << endl; } return 0; }