2013-05-03 1 views
2

텍스트 파일의 라인을 변수 myline에 읽어 들인 다음 istringstream을 사용하여이 라인을 토큰 화하려고합니다. 그러나 원래 텍스트 파일 문자열에서 임의의 문자가 손실되는 것으로 보입니다.istringstream을 사용하여 임의의 문자를 잃는 경우

cout<< myline << buff << flush; //print original text file line 
istringstream iss(myline); 
string sub; 
while (iss >> sub) { 
cout << "[" << sub << "]" << endl; 
} 

내 출력을 보면, 당신은 내가 텍스트 파일에서 올바른 문자열을 볼 수 있습니다,하지만 난 istringstream를 사용할 때 다음, (괄호 [] 내에서 볼)의 일부를 개별 토큰을 인쇄 토큰이 조기에 잘 렸습니다.

#include <iostream> 
[#include] 
[<iostream] 
#include <sstream> 
[#include] 
[<sstream>] 
using namespace std; 
[using] 
[namespace] 
[st] 

int main() 
[int] 
[main(] 
{ 
    string str(" SOME LONG STRING\twith\nSPACES "); 
[string] 
[str("] 
[SOME] 
[LONG] 
[STRING\twith\nSPACES] 

    istringstream iss(str); 
[istringstream] 
[iss(str);] 

    string s; 
[strin] 
    while (iss >> s) { 
[while] 
[(iss] 
[>>] 
     cout << "[" << s << "]" << endl; 
[cout] 
[<<] 
["["] 
[<<] 
[s] 
[<<] 
["]"] 
[<<] 
[e] 
    } 
    return 0; 
[retur] 
} 

아무도 내가 잘못하고있는 아이디어가 있습니까? 미리 감사드립니다!

편집 : 다음은 완전히 컴파일 될 코드의 버전입니다. 당신은

#include <cstring> 
#include <cstdio> 
#include <iostream> 
#include <iomanip> 
#include <string> 
#include <sstream> 
#include <vector> 
#include <algorithm> 
#include <iterator> 

using namespace std; 

class MyFileReader { 

public: 
    //constructor 
    MyFileReader(const char* p); 

    //destructor 
    ~MyFileReader(); 

    //getLine() 
    int getLine(char *buffer, int size); 

    //getCurrentLineNumber() 
    int getCurrentLineNumber(); 

    void tokenizeLine(vector<string>& vec); 

    FILE * pFile; 

}; 

    //constructor 
    MyFileReader::MyFileReader(const char* p) { 
     pFile = fopen(p, "r"); 
    } 

    //destructor 
    MyFileReader::~MyFileReader() { 
     fclose(pFile); 
    } 

    //getLine() 
    int MyFileReader::getLine(char *buffer, int size){ 
     char *out = fgets(buffer, size, pFile); 
     if (out==NULL) { 
      return -1; 
     } 
     char *pch = strpbrk(out,"\n"); 
     if (pch != NULL) { 
      return 1; 
     } 
     else { 
      return 0; 
     } 

    } 

    int MyFileReader::getCurrentLineNumber() { 
     static int mynumber=2; 
     return mynumber++; 
    } 

    //tokenizeLine 
    void MyFileReader::tokenizeLine(vector<string>& vec) { 
     string myline(""); 
     char buff[10]; 
     while (1) { 
      int result = getLine(buff, sizeof(buff)); 
      if (result == -1) { 
       if (myline.length() > 0) 
        cout << myline << flush; 
      break; 
      } 
      else if (result == 0) { 
       myline += buff; 
      } 
      else if (result == 1) { 
       cout<< myline << buff << flush; 
       istringstream iss(myline); 
       string sub; 
       while (iss >> sub) { 
        cout << "[" << sub << "]" << endl; 
       } 
       myline = ""; 
      } 
      else { 
       printf("PANIC"); 
      } 
      } 
      return; 
     } 

    int main(int argc, char **argv) { 
    vector<string> v; 

    const char *filename = argv[1]; 
    MyFileReader f(filename); 
    f.tokenizeLine(v); 
    return 0; 

    } 

위의 출력을 생성하는 텍스트 파일을 실행할 수 있습니다, 내가 그것을 실행 :

#include <iostream> 
#include <sstream> 
using namespace std; 

int main() 
{ 
    string str(" SOME LONG STRING\twith\nSPACES "); 

    istringstream iss(str); 

    string s; 
    while (iss >> s) { 
     cout << "[" << s << "]" << endl; 
    } 
    return 0; 
} 
+1

[SSCCE] (http://sscce.org/) + 원래 입력은 좋을 것입니다 – dyp

+0

.. 오류 ... cannot .. 재현 ... 필요 ... 코드의 더 많은 것 ... – dyp

+0

edited 컴파일 가능한 코드 @DyP – user2348283

답변

1

실수는 여기에 있습니다 :

else if (result == 1) { 
      cout<< myline << buff << flush; 
      istringstream iss(myline); 
      string sub; 
      while (iss >> sub) { 
       cout << "[" << sub << "]" << endl; 
      } 
      myline = ""; 
     } 

result == 1하는 경우, 즉, 그 buff\n을 포함하지만, 그것을 의미하지는 않습니다. co 네가 \n. 나는. 버퍼가 \n이면 버퍼를 삭제합니다. 따라서 줄에 n * 10 (버퍼 크기) 문자가 있으면 코드가 작동하고 그렇지 않으면 줄의 마지막 문자는 myline으로 복사되지는 않지만 삭제됩니다. 당신이 좋아하는 버퍼에서 \n을 삭제 고려할 수 있지만

else if (result == 1) { 
      myline += buff; // copy the rest of the line into `myline` 
      cout<< myline << flush; // buff now is part of myline 
      istringstream iss(myline); 
      string sub; 
      while (iss >> sub) { 
       cout << "[" << sub << "]" << endl; 
      } 
      myline = ""; 
     } 

:

빠른 수정하는 것입니다 당신은 cout<< myline << endl;cout<< myline << flush;을 변경해야

int MyFileReader::getLine(char *buffer, int size){ 
    char *out = fgets(buffer, size, pFile); 
    if (out==NULL) { 
     return -1; 
    } 
    //char *pch = strpbrk(out,"\n"); 
    char *pch = strchr(out,'\n'); // no need to search for a string 
    if (pch != NULL) { 
     *pch = '\0'; // drop the '\n' 
     return 1; 
    } 
    else { 
     return 0; 
    } 

} 

, 그래도.


이 실수 외에도, ifstream 사용을 고려하십시오

#include <iostream> 
#include <fstream> 
#include <sstream> 
using namespace std; 

int main() 
{ 
    ifstream file("test.txt"); 
    if(!file) 
    { 
     /* error */ 
    }else 
    { 
     string line; 
     while(getline(file, line)) 
     { 
      istringstream iss(line); 

      string s; 
      while (iss >> s) { 
       cout << "[" << s << "]" << endl; 
      } 
     } 
    } 
} 
+0

감사! 나는 버퍼의 나머지를 고려하지 않았다, 그것은 많은 의미를 가진다. – user2348283

1

당신의 라인 버퍼는 10 바이트입니다. 전체 길이에 맞을만큼 길지는 않습니다.

void MyFileReader::tokenizeLine(vector<string>& vec) { 
     string myline(""); 
     char buff[10];// this is too short 
.... 

편집

는 Dyp가 올바르게 입력 파일에 \ n을 감지 할 때 추기 논리가 정확하지 지적한다.

+1

그러나 OP는'myline'을 사용하여 버퍼를 추가하여 라인을 만듭니다. 'myline + = buff; ' – dyp

+0

예 DyP가 맞습니다. 나는 거기에서 조금 빨리 승진했다.게시물을 편집하여이를 나타냅니다. –

+0

고마워! 나는 나의 if 진술을주의 깊게 고려하지 않고 왜 내 결과물이 기대와 다른지 궁금해했다. – user2348283

관련 문제