:: 게시판
:: 이전 게시판
|
이전 질문 게시판은 새 글 쓰기를 막았습니다. [질문 게시판]을 이용바랍니다.
통합규정 1.3 이용안내 인용"Pgr은 '명문화된 삭제규정'이 반드시 필요하지 않은 분을 환영합니다.법 없이도 사는 사람, 남에게 상처를 주지 않으면서 같이 이야기 나눌 수 있는 분이면 좋겠습니다."
09/10/20 00:47
일반적인 경우라면 저렇게 getline 쓸 때 아무리 긴 스트링이라도 (메모리가 허용한다면) 제대로 받아지는데 말이죠.
첫줄에 원인이 대충 뭔지 아십니다.....와 뭔가 다른 이유나 연관이 있나요?_?
09/10/20 00:49
getline으로 문자열 받는것 자체는 문제가 안되는데
이것을 직렬화 시켜서 파일에 저장하고 불러들일때 문제가 됩니다. 확인해본 결과 문자열 길이가 15개를 넘어서면 저 오류가 발생하고 15개까지는 이상이 없었습니다. 구체적인 원인을 모르겠지만 일단 발생하는 조건을 알아낸 것으로 만족하고 있는 상황입니다.
09/10/20 00:59
간단하게 테스트 해본 결과 되는 것 같은데요?
혹시 제가 한 것이 님 의도와 다른 프로그램인지요? #include <iostream> #include <string> using namespace std; int main() string strname; getline(cin,strname); cout << strname;
09/10/20 01:13
ifstream과 ofstream의 ios 속성중 binary로 read write하는 것이 있습니다.
이것을 이용하는 문제였습니다.
09/10/20 01:20
#include <iostream>
#include <string> #include <fstream> using namespace std; int main() string strname; fstream file; file.open("rm.txt",ios_base::binary | ios_base::out); getline(cin,strname); file << strname; file.close(); 파일 스트림을 사용한 출력도 별 문제가 없는데요?
09/10/20 01:25
ifstream과 ofstream으로 나누시고
ofstream 객체로 "객체를" write하신 다음에 ifstream 객체로 "객체를" read하시면 다를겁니다. class temp ... temp t,t2; ofstream fout; fout.open(...); fout.write((char *)&t, sizeof t); ifstream fin; fin.open(....); fin.read((char *)&t2, sizeof t2); 이 방식이 제가 사용하는 방식입니다.
09/10/20 02:05
#include <iostream>
#include <string> #include <fstream> using namespace std; class temp public: temp() { ~temp() string strname; }; int main() temp t,t2; getline(cin,t.strname); ofstream fout; fout.open("rm.txt", ios_base::out); fout.write((char *)&t,sizeof(t)); fout.close(); ifstream fin; fin.open("rm.txt",ios_base::in); fin.read((char *)&t2, sizeof(t2)); fin.close(); cout << t2.strname; 이 방식으로 테스트 한 번 해보세요. out file을 열고 나서 닫지 않고 접근을 해서 그럴수도 있으니 close()는 반드시 해주시고...
09/10/20 02:08
아... 출력부를 지나고 프로그램 종료시에 에러가 나는군요.
제 생각에는 동적 메모리를 사용하는 string이 클래스 안에 있어서 그걸 직렬화 하는데 문제가 있는 것 같네요. 까다로운 상황 같은데 전에 STL관련해서 이런 비슷한 질문이 있었던 것 같은데 참고해보셔도 좋을듯 합니다.
09/10/20 02:13
저 같으면 동적 할당보다는
#include <iostream> #include <string> #include <fstream> #define MAX_INPUT 100 using namespace std; class temp public: temp() { ~temp() char strname[MAX_INPUT]; }; int main() temp t,t2; gets(t.strname); ofstream fout; fout.open("rm.txt", ios_base::out); fout.write((char *)&t,sizeof(t)); fout.close(); ifstream fin; fin.open("rm.txt",ios_base::in); fin.read((char *)&t2, sizeof(t2)); fin.close(); cout << t2.strname; 이렇게 해결하지 싶은데 이 방법은 elegant 하지 않아 별로인가요? 흐흐
09/10/20 02:14
그렇게 하고 싶어도 지금 string으로 작성한 부분이 많은데다 2차원 배열 생성이 필요한 부분이 많아서 그러질 못하고 있습니다...
09/10/20 10:15
C++ 몰라서 답변 달까 말까 했는데, 간단히 테스트를 해보니 상황은 t2의 destructor에서 발생하는 거 같습니다. 제가 생각하기엔 원인은 size는 t에서 정해졌고, t2에서는 size가 0인 상태로 그대로 t의 데이터를 써넣다보니 오류가 발생한 거 같습니다(물론 원래 의도가 t2는 0인 상태에서 파일을 읽어 쓰는 거라면 뭐... 할 말이 없네요 -_-).
아무튼 그래서 gdb를 통해 살펴봤더니 그게 원인인 듯 싶어, temp class에 char[]를 넣어서 입출력을 해주고, member function을 추가해 strname은 char[]에서 복사를 해주도록 바꿔봤더니 죽지 않네요. 그리고 destructor에는 strname의 size가 0이 아닌 경우 clear()를 호출해줬습니다. 제가 C 프로그래머라서 C++에 대해 뭐라 조언을 할 입장은 아닌데, 아시겠지만 결국 C/C++에서 공통적인 것은 memory 관리가 거의 대부분의 문제의 원인이라는 점입니다. C++의 내장 class를 사용하면 C 보다는 진보한 형태로 memory 관리를 class에서 해주지만 그 의도를 정확히 파악을 못하면 결국 오히려 C보다 훨씬 복잡해집니다. 그래서 조언드리고 싶은 것은... 지금 string으로 작성한 부분이 많아서 포기 못하는 것을 버려야 한다는 점입니다. 왜냐하면 지금 설계에 문제가 생겨서 원하시는 부분과 원래 있던 부분이 충돌을 해서 해결을 못하는 상황이 왔으니까요. 아무튼 잘 해결해보세요. 저도 그럼 이만 일하러... ^^
09/10/20 12:21
예전에도 말씀드린 것 같습니다만....
string같이 라이브러리 내부적으로 메모리 관리를 하는 클래스는 클래스가 가진 메모리 자체를 파일에 썼다가 읽으면 위험합니다. string이 내부적으로 관리하는 메모리 주소의 내용은 언제든지 바뀔 수 있는데 string의 메모리값을 그대로 썼다가 읽었는데 그 사이에 가리키던 메모리 주소의 상황이 바뀌면 잘못된 동작을 할 수가 있습니다. 지금 예에서는 15글자까지는 우연히 문제가 안생기다가 그이상 넘어가는 순간 메모리가 엉키는 문제로 보입니다. string을 다룰 때는 string이 가지고 있는 문자 데이터만 쓰고 읽도록 해야 할 것 같습니다.
09/10/20 13:37
잘 아시는 것처럼 string은 단순한 struct가 아닌 class죠. 따라서 fwrite/fread로 쓰고 읽는 것 자체가 문제로 보입니다. string의 내용을 binary로 읽고 쓸려면 method를 이용해서 하시는 게 맞겠죠.
09/10/20 22:07
많은 분의 답변 감사합니다.
이것 참 고민이네요... 어제 새벽녘까지 잠을 포기하면서 char배열로 바꾸고 스트링 배열은 char의 이차원배열로 생성하여 더블포인터로 입출력을 받게 했는데... 이놈의 포인터때문에 참 고생만 늘어나네요 ㅠㅠ
|