2014-12-02 1 views
1

내 코드는 아래에 게시됩니다. 구분 기호 "()"를 사용하여 구문 분석하고 문자열을 cpp의 정수로 변환 할 수 있기를 원합니다. 134 : 오류 : '숯불 *'C++에서 getline과 strtok을 사용하여 여러 구분자를 구문 분석하는 방법에 대해 매우 혼란 스럽습니다.

GraphTest.cpp에 'const를 숯불 *'에서 유효하지 않은 변환 : (134)

while(getline(fin, line)) 
{ 
    x = atoi((strtok(line.c_str(),'(,)')); 
    xx = atoi((strtok(NULL,"(),")); 
    xxx = atoi((strtok(NULL,"(),"))); 
    cout << x << " " << xx << " " << xxx << "\n"; 
} 

하지만 어떤 이유로 내가 할 다음과 같은 오류

GraphTest.cpp

: 오류 : 'char * strtok (char *, const char *)'의 인수 1 초기화

.c_str은 내 문자열을 ac 유형 문자열로 변환해야 atoi 및 strtok 함수를 사용할 수 있습니다. 나는 매우 혼란스럽고 어떤 도움을 주셔서 감사합니다.

+0

은 평범하지 않은 문법을 사용하는 것처럼 보입니다. 렉싱 및 파싱에 적합한 도구를 선택하십시오 (예 : flex + bison 또는 boost spirit ...). –

+0

' '(,)' '가 잘못되었습니다. 그것은''(,) "'이어야합니다. –

+1

'c_str()'은'const char *'를 반환합니다. 이것은 문자열 내부 버퍼에 대한 수정 불가능한 상수 포인터입니다. 'strotok()'**는 토큰 화를 수행하기 위해 입력 문자열을 수정합니다 (그래서 const char * 대신 char *를 받아들입니다). –

답변

0

c_str()const char*을 반환하기 때문에 컴파일되지 않습니다. 수정 불가능한 내부 버퍼 string에 대한 상수 포인터로 간주됩니다. 반면에 strtok()은 입력 문자열을 수정하기 때문에 char*을 허용합니다.

이제 두 가지 옵션을 사용할 수 있습니다. strtok()에서 사용할 수있는 C 문자열을 얻거나 모든 것을 C++로 다시 작성하십시오.

은 C++ 문자열에서 새 수정 C 문자열을 만듭니다

char* modifiableLine = strdup(line.c_str()); 

x = atoi((strtok(modifiableLine, "(,)")); 
// Other processing 

free(modifiableLine); 

당신이 C++ 함수/클래스 내부에 랩 C 코드의 양을 유지해야하는 경우 당신은 그것을 할 수 있습니다. 더 나은 해결책은 C++ 표준 라이브러리가 제공하는 것을 사용하는 것입니다 (C++ 11의 경우 C 함수 인 atoi() 삭제).

int readNextInt(istringstream& is, const string& delimiters) { 
    string token; 

    if (getline(is, token, delimiters)) 
     return stoi(token); 

    return 0; // End of stream? 
} 

과 같이 사용 :의는 먼저 도우미 함수를 만들어 보자

istringstream is(line) 
x = readNextInt(is, "(),"); 
xx = readNextInt(is, "(),"); 
xxx = readNextInt(is, "(),"); 

표준 C++ 기능 getline()은 다음에이 구분 기호 매개 변수에 대한 string하지만 하나의 char을받지 않습니다 자신 만의 오버로드 된 버전을 작성하십시오. 가능한 좋은 구현을 위해 this post을 살펴보십시오. 을 is >> token으로 바꿀 수도 있습니다 (예 : is.imbue()).

음 ... 이미 Boost를 사용하고 있다면 boost::tokenizer을 사용해도됩니다.

0

여러 구분 기호로 구문 분석 할 필요가있는 비슷한 문제가있어서 어디에서나 좋은 해결책을 찾을 수 없어서 결국 함수를 만들었습니다.

string getlineMultDelimiter(istream &is, string dlm, bool includeDelimiter) 
{ 
    string str; 
    char c; 
    bool found = false; 

    while (!found && is) 
    { 
     for (size_t i = 0; i < dlm.length() && !found; ++i) 
      found = dlm[i] == is.peek(); 

     if (!found || includeDelimiter) 
     { 
      is.get(c); 
      str += c; 
     } 
    } 
    return str; 
} 

IT는 구분 기호로 DLM 문자열의 모든 문자를 사용하면 반환 된 문자열에서 구분 여부를 포함할지 여부를 선택할 수 있습니다.

관련 문제