[완료] C++ 에서 텍스트 파일을 읽을때 주석 제거하기
글쓴이: jinserk / 작성시간: 목, 2009/11/19 - 1:34오전
어떤 config.txt 가 다음과 같을때
# comment 1 2 3 4 #5 6
1,2,3,4 만 읽고 싶습니다.
이를 위해서 다음과 같이 주석을 제거하는 코드를 작성해 봤습니다.
34 std::ifstream ifs(syscfg_file.c_str()); 35 if (ifs.fail()) 36 error("file does not exist"); 37 38 char tmp[256]; 39 std::istringstream iss; 40 while (!ifs.eof()) { 41 ifs.getline(tmp, 256); 42 std::cout << tmp << std::endl; 43 iss.str(tmp); 44 std::cout << iss.str() << std::endl; 45 iss.getline(tmp, 256, '#'); 46 std::cout << tmp << std::endl;
그런데, 46번 행에서 # 앞부분만 나올것으로 기대했건만,
아무것도 나오질 않네요.
질문 1. # 이후를 무시한 주석 제거 알고리듬을 C++ 로 어떻게 구현하면 될까요?
질문 2. 공백과 \n 으로만 이루어진 행은 어떻게 제거하면 될까요?
Forums:
그냥 고민안하고
그냥 고민안하고 한다면 getline해서 '#'으로 split해서 뒷부분은 버리면 됩니다.
화이트스페이스는 trim 합니다.
그런데, 이 목적만이 아니고 interpreter처럼 만들려고 하면, 그냥 lexer를 손으로 만듭니다.
lexer를 손으로 만드는게 귀찮거나, 수정사항이 많다면 lex를 씁니다.
따로 파일놔두고 관리하기 싫어서 lex가 별로라면, spirit을 씁니다.
------------------------------
How many legs does a dog have?
------------------------------
How many legs does a dog have?
getline 에 delim 을 #
getline 에 delim 을 # 으로 쓴다면
주석이 없는 행을 읽을때 그 다음줄까지 읽어버리지 않는지요? (즉, \n 에서 분리하지 않는게 아닌가..)
게다가 white space 만 있는 행도 하나의 line 으로 읽을텐데
그 경우는 변수들을 읽어들이다 에러가 날 수도 있겠구요.
지금 하려는 것은 하나의 행에 정해진 수의 값들이 있다고 가정하고
그만큼 읽어들일 생각이라서..
Leo.
문법정의를 하시는게 좋을 것 같긴 합니다.
제 생각에는 semmal님의 방식이 깔끔해 보입니다.
istringstream을 쓰시는 걸로 봐서는 C++ 표준 library에 익숙하실 것 같은데 조금만 더 고민하시면 해결하실 수 있을 것 같네요.
Andrew Koenig의 Accelerated C++에서 URL 인식이 들어있던 것으로 기억합니다. 참고하시면 도움이 되실 것 같습니다.
좀더 문제를 명확히 해보겠습니다.
1. 읽으려는 text 파일에는 N 열의 상수가 있습니다. 상수는 int, float, char 가 혼합되어 있습니다.
2. # 으로 시작하거나 한 행에서 # 이후는 comment 로 무시합니다.
3. whitespace 만으로 이루어진 행 역시 무시합니다.
예제: N = 3
윗분들께서 말씀해주신대로 다음과 같이 코딩을 해봤습니다.
그리고 나서 아래와 같은 text 파일로 테스트를 해봤습니다.
결과입니다.
우선 a, b, c 에 제대로 값이 들어가지 않구요,
주석행도 하나의 행으로 읽어 버리고
그리고 공백문자 제거도 안되는 듯 합니다.
다시금 조언을 구합니다.
감사합니다.
Leo.
다 하셨네요.
http://www.cplusplus.com/reference/iostream/istringstream/str/
꼼꼼히 읽어보시고, 문제점은 약간만 생각해보시면 될겁니다.
읽는건 어찌 됐는데
코드를 아래와 같이 바꾸니까 일단 값을 읽는건 되네요.
iss 를 미리 생성하고 str() 로 스트링만 업데이트 해서는 buffer 와 sync 가 안되는
모양입니다. 그래서 while 내부에서 iss 를 생성하는걸로 바꾸니까 일단 iss 에서
값을 읽는 건 동작합니다.
문제는.. 위에 언급한대로 주석행이나 데이터 열이 N 이 안되는 행들은
에러 처리가 되지 않아서 역시 쓰레기값이 들어간다는 점입니다.
iss 가 비어 있더라도 >> operator 는 에러를 내질 않네요. :(
Leo.
해결했습니다.
iss.str() 은 fail / eof bit reset 을 안한다는게 키 였군요.
도움 주신 분들께 감사드립니다. :)
Leo.
댓글 달기