2014-11-25 2 views
0

csv 파일을 처리하는 데 약간의 문제가 있습니다. 저는 C++에 익숙하며 배우려고합니다. 그것은 아마도 내가 간과하고있는 작은 일이지만 온라인에서 답을 찾았고 내가 어디로 잘못 가고 있는지 알 수 없습니다. 여러 줄 및 쉼표로 구분 된 값을 가진 파일을 처리하려고합니다. 줄의 끝에 쉼표가 없어도 차이가 있습니다. - 참고로, 텍스트를 게시하려고했을 때, 문단 나누기, 그 차이를getline을 사용하여 csv 처리시 명확하지 않은 동작이 발생했습니다.

판매를 만드는 경우, manually-- 확실하지 않은 11/9/14,11/9/14 AMAZON MKTPLACE PMTS, -8.99

판매를 것을 추가했다 10/4/14,10/5/14 AMAZON MKTPLACE PMTS, -13.08

판매/3/14,10/14분의 5 10 아마존 MKTPLACE PMTS, -9.82

S

ALE/2/14,10/14분의 3 10 아마존 MKTPLACE PMTS, -45.48

판매 8/21/14,8/22/14 AMAZON MKTPLACE PMTS, -9.99

판매, 8분의 11/14,11/9/14 Amazon.com, -64.7

판매 10/1/14,10/20/14 * APL ITUNES.COM/BILL,-1.08

판매,/15/14,9/14분의 16 (9), APL * ITUNES.COM/BILL,-1.08

나는 다음 stringstream으로 각 라인을 얻을 수 getline를 사용하여 시도 아래의 코드를 사용하여 구분 기호 쉼표 (,)로 그 라인의 각을 구문 분석 :

ifstream file("test1.csv"); 
string value, line; 
while (getline(file, line)) { 
    stringstream linestream(line); 
    while (getline(linestream, value, ',')) { 
     cout << "Value: " << value << endl; 
    } // while 
    cout << "Done Procesing" << endl; 
} // while 

을 내가 얻고 문제는 쉼표의 모든 5 토큰 후 어떤 이상한 이유로 단어 “Sale”를 처리 구분 된 것은 말씀을 덮어이다 Value 및 이유를 이해할 수 없습니다. 약간의 지침을 정말로 바르게 평가할 것입니다.

+0

사용, 아마 예를 들어, linestream 작성하기 전에 '\r' 문자를 제거, 다른 접근 방식을 필요, '))'구분 기호를 쉼표로 지정하십시오. 줄 끝에 쉼표가 없습니다. – druckermanly

+4

입력 파일에는'\ r \ n' 시퀀스로 구성된 DOS 스타일의 줄 끝이 포함되어있을 것입니다. 'getline()'은'\ r'을'line'으로 읽어들이므로 각 줄의 마지막 값은 캐리지 리턴을 포함합니다. –

+0

@ user2899162이므로'linestream'에는 한 줄만 포함되어 있기 때문에이 경우에는 현재 줄의 끝 부분 인 EOF로 읽습니다. –

답변

1

설명에 따라 (그러나 인용 된 텍스트에는 표시되지 않음) 각 줄은 '\r' (캐리지 리턴) 문자로 시작됩니다. 일부 시스템에서는 행 순서의 끝을 사용합니다. Windows는 일반적으로 binary 모드가 아닌 파일을 열 때 (즉, 스트림을 만들 때 std::ios_base::binary 플래그를 전달하지 않을 때) 하나의 '\n'으로 바뀌는 "\r\n" (캐리지 리턴, 줄 바꿈)을 사용합니다. 그러나이 대체 코드는 이 아니며 "\ n \ r"시퀀스에 대해이 아닙니다.

당신은 쉽게 std::istringstream (I 읽기/쓰기 스트림이 생성되어야하는 이유가 표시되지 않습니다 거기에 추가 i 하락)을 생성하기 전에 모든 '\r' 문자를 대체하여이 이론을 검증 할 수

:

std::transform(line.begin(), line.end(), line.begin(), '\r', '@'); 
std::istringstream linestream(line); 
을 이러한 변화와

나는 첫 번째 줄하지만 모두의 첫 번째 단어의 출력은 다음과 같이 것이라고 예상 :

Value: @Sale 

문제를 해결하는 가장 쉬운 방법은 단순히 선도 공백을 생략하는 것입니다 줄을 읽을 때.해당 코드의 발췌는 다음과 같이 보일 것이다 : 간단하게 모든 주요 공백을 제거 라인을 읽을 때

std::ifstream file("test1.csv"); 
for (std::string line; std::getline(file << std::ws, line);) { 
    std::istringstream linestream(line); 
    for (std::string value; std::getline(linestream, value, ',');) { 
     std::cout << "Value: " << value << '\n'; 
    } // for 
} 
std::cout << "Done Procesing\n"; 

마법은 << std::ws의 추가이다. 이 코드는 inappropriate use of std::endl도 제거합니다. 각 행의 첫 번째 단어가 공백을 선도 포함 할 경우에 당신은 동안 (의 getline (linestream, 가치, '문'에서

line.erase(std::remove(line.begin(), line.end(), '\r'), line.end()); 
관련 문제