2013-01-28 3 views
5

그래서 두 번째로 연결된 목록에 성과 이름을 추가하려고 시도하고 있습니다. "string, string"형식의 다양한 길이의 다양한 텍스트 파일을 보유하고 있으며 목록을 사용하여 데이터를 저장합니다.목록 및 쌍에 대한 혼동

이 코드를 사용하고 있습니다 :

typedef std::list< std::pair<string,string> > listPair; 

...

list<pair<string, string> > mylist; 
ifstream myFile; 
myFile.open("20.txt"); 

pair<string, string> stuff; 
while (myFile >> stuff.first >> stuff.second) 
{ 
    mylist.push_back(stuff); 
} 

listPair::iterator iter = mylist.begin(); 

for(;iter != mylist.end();iter++) 
{ 
    string s = (*iter).first; 
    cout << s << endl; 
    string c = (*iter).second; 
    cout << c << endl; 
} 

지금 제가하는 데 문제는 첫째, 목록의 마지막 항목이 추가되지 않는 것입니다. 모든 파일이 마치 최종 줄을 놓친 것처럼 약간 혼란 스럽습니다.

또한 모든 이름이 추가되었는지 확인하기 위해 mylist.size()를 사용하고 있으며 99 개의 이름 (예 : 99 줄의 텍스트)이 포함 된 텍스트 파일에 대해 말하기 때문에 혼란 스럽습니다. (마지막 줄이 없어서 98로 읽는 것을 잊지 않고) 목록의 크기는 48입니다.

왜 48입니까? 쌍을 이루었 기 때문에 쌍을 이루었 기 때문에해야 할 일이 있습니다. 쌍으로 읽지 않는 것처럼 이해할 수는 없지만 사실상 쌍은 약 두 가지가 될 것입니다. 그 쌍은 이름과 성을 하나의 값으로 취하기 때문입니다.

나에게 소리가 난다.

다시 한번 감사드립니다.

+0

아마도 'getline'을 찾고 있을까요? –

+2

보조 노트와 마찬가지로, 범용 컨테이너로'list'보다는'vector'를 사용해야합니다. 당신이 그것을 사용하는 방식에서, 나는 여기에'목록'의 필요성을 보지 못했다. –

+0

입력 파일'20.txt' (또는 적어도 추출 파일)을 추가 할 수 있습니까? 입력 내용의 형식이 잘못되었을 수 있습니다. – Zeta

답변

5

내가 가지고 당신이 설명한대로 다음과 같습니다 그래서 실제로 값 사이에 공백이없는 파일을 느낌 : 당신이 당신의 프로그램을 실행한다면

one,two 
three,four 
five,six 
seven,eight 
nine,ten 

, 크기 list의 숫자는 2 (floor(number_of_lines/2), 이는 48을 부여합니다)이며 마지막 줄은 list에 전혀 입력되지 않습니다. 왜?

첫 번째로 std::ifstream::operator>>(std::string&)을 호출 할 때마다 공백이 생길 때까지 추출됩니다. 이 경우 첫 번째 줄의 첫 번째 공백은 \n입니다. 따라서 첫 번째 반복에서는 stuff.first"one,two"이 될 것이고 다음 줄은 stuff.second으로 읽혀 "three,four"이됩니다. 그런 다음 list에 푸시됩니다. 다음 두 줄은 동일한 방법으로 읽혀서 {"five,six","seven,eight"} 쌍을줍니다. 다음 반복에서 첫 번째 operator>>"nine,ten"을 추출하고 두 번째는 실패하며 while 조건이 종료되고 마지막 줄이 삭제됩니다.

공백이 있어도 first (pair)의 쉼표로 끝나야합니다. 이는 분명히 원하는 것이 아닙니다.

분석 한 후 적절한 그 라인을이 라인을 추출하는 std::getline을 사용하는 것입니다 같은 문제를 접근하고, 할 수있는 더 좋은 방법은 : 당신이 사용하는 좋은 이유가없는

std::string line; 
std::pair<std::string, std::string> line_pair; 
while (std::getline(myFile, line)) { 
    std::stringstream line_stream(line); 
    std::getline(line_stream, line_pair.first, ','); 
    std::getline(line_stream, line_pair.second); 
    mylist.push_back(line_pair); 
} 

또한 std::vector를 사용하는 것이 좋습니다 std::list.

+0

고마워, 이건 내 문제 야. 완벽하게 작동 했어! gosh는 매일 새로운 것을 배웁니다. 하하 –

-1

ifstream의 연산자 > >은 개행을 또 다른 토큰으로 취급합니다. 따라서 첫 번째 줄에서 평상시와 같이 첫 번째 및 두 번째 단어를 읽지 만 세 번째 토큰은 첫 번째 줄에서 새 줄을 읽습니다.

줄 바꿈을 사용하여 줄 바꿈을 사용해보십시오.

+3

추출기는 다른 모든 공백과 마찬가지로 새 줄을 처리합니다. 'operator >>'를 일관성있게 사용한다면 주위를 건너 뛰지 않아도됩니다. –