강의 시간에 재밌는 과제를 받았다.
fstream 내의 ofstream, ifstream 으로 std::string 을 binary mode로 읽고 쓰기 였다.
많은 방법이 있겠지만, 내가 활용한 방식은 이렇다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | #include <iostream> #include <fstream> #include <string> using namespace std; struct A { std::string mystr; int myint; }; int main() { A onlywrite; onlywrite.mystr= "abcd"; onlywrite.myint= 4; ofstream out("read.txt", ios::binary); out.write(onlywrite.mystr.c_str(), onlywrite.mystr.size()); out.write((char*)&onlywrite.myint, sizeof(int)); out.close(); A onlyread; ifstream in("read.txt", ios::binary); onlyread.mya.resize(onlywrite.mystr.size()); in.read(&onlyread.mystr[0], onlywrite.mystr.size()); in.read((char*)&onlyread.myint, sizeof(onlyread.myint)); cout << mimi.mystr<< mimi.myint<< endl; } | cs |
일단 std::string 은 내부적으로 char* 형을 가지고 있기때문에, 바이너리로 그냥 쓴다면 포인터의 주소값만 적히게 된다.
만약 onlywrite 자체를 write 한뒤 onlyread 에서 read 하면, 그냥은 읽어지지만 그건 사실 onlywrite 의 char*의 주소값만 읽어온거라 읽어 온 것 처럼 보이게 된다.
이 오류는 끝나면 알 수 있는데, std::string 내의 iterator 가 onlywrite를 delete 한 후, onlyread 를 delete 할 때 exception 을 일으키게 된다.
아마 std::string 에 대해 잠깐 공부해보면 왜 그런지 알 수 있을 것이다.
이에 대한 수정 방안으로, std::string 안에 있는 c_str() 함수를 이용했다.
이 함수는 std::string 내부에있는 동적할당 된 char* 타입을 꺼내주는데 이를 통해 size 만큼 txt에 작성하고, 읽어 올 수 있다.
위의 소스도 그와 동일하게 onlywrite.mystr.c_str() 을 통해 onlywrite 의 char* 타입을 꺼내 size 만큼 txt에 작성하고,
그것을 size 만큼 다시 읽어와 onlyread 의 mystr에 붙혀넣어주었다.
주의점은
onlyread는 size만큼의 여유분을 확보하고 있어야 한다. (resize 활용)
이를 통해 onlyread.mystr[0]에 값을 넣어준다 ( mystr[0] 는 char*의 0번째 이다. std::string 이 내부적으로 operator[] 를 오버로딩 하고있기때문 )
만약 이것을 배열로 사용한다면, onlywrite[?] 의 배열만큼 size도 txt에 추가 작성해주어야 할 것이다.
size, txt 이렇게 말이다.
그럼 size를 먼저 읽어와 resize를 통해 공간을 확보하고, txt를 읽어와 붙혀넣어주면 된다
해결!
'C++ > 여담' 카테고리의 다른 글
C++20 draft 와 모든 feature (0) | 2021.01.11 |
---|---|
직접 제작한 게임들의 동영상을 게시하고 있습니다. (0) | 2020.08.10 |
3주차 강의내용 정리 (0) | 2019.03.24 |
1주차 강의 내용 정리 (0) | 2019.03.09 |
2019-02 C++ 표준 위원회 보고서 (0) | 2019.02.24 |