2014-12-17 9 views
-1

기본적으로 .txt 파일을 읽고 값을 저장하고 있습니다. 예를 들어istream 연산자 >> ' n'문자를 인식하지 않습니다.

:

Student- Mark 
Tennis 

이는 studentName 같은 Mark 메모리에 저장한다. 그냥

Student- 
Tennis 

경우

지금 ... 그 다음은 잘 작동하고 오류가 발생합니다. 파일이

Student-(space)(nothing here) 
Tennis 

과 같은 경우에 실제로 경우 아무것도 저장하지 않고 오류가 발생한다 때

그러나, 그것은는 studentName으로 메모리에 Tennis를 저장합니다. - 문자 뒤에 아무 것도 없는지 확인하려면 '\n' 문자를 사용합니다. 이

istream& operator>> (istream& is, Student& student) 
{ 
    is.get(buffer,200,'-'); 
    is.get(ch); 
    if(is.peek() == '\n') 
    { 
     cout << "Nothing there" << endl; 
    } 
    is >> ws; 
    is.getline(student.studentName, 75); 
} 

나는 is.peek() 공백을 인식하기 때문에이 생각,하지만 난 is >> ws를 사용하여 공백을 제거하려고하면 다음, 그것은 '\n' 문자를 제거하고 여전히 studentNameTennis 저장 ... 내 코드입니다.

누군가이 문제를 해결할 수 있다면 많은 도움이 될 것입니다.

+3

당신입니다. peek() =='\ n' ..... 이것이 사실이라면 함수에서 리턴해야합니다. – ha9u63ar

+0

find_first_of() 함수를 사용하면 제거 할 공간을 인식 할 수 있도록 첫 번째 공백을 찾을 수 있습니다. –

+0

캐리지 리턴을 고려하면 '\ n \ r'이어야합니다. – ha9u63ar

답변

0
당신이 공백 무시하려면

하지만 하지'\n' 당신은 쉽게 std::ws을 사용할 수 없습니다 : 그것은 ' ' 문자 '\n' (줄 바꿈), '\t' (탭), 및 '\r' (캐리지 제외하고 모든 공백을 건너 것이다 반환) 공백으로 간주됩니다 (나는 실제로 몇 가지 더 있다고 생각합니다). 은 스트림의 어떤 공백을 의미하는지 다시 정의 할 수 있습니다 (스트림의 std::locale을 공백 문자의 의미를 변경 한 사용자 정의 std::ctype<char> 패싯으로 바꿈으로써). 그러나 이것은 아마도 조금 더 진보 된 것입니다. 그 일을 즉시 할 수있는 소수의 사람들, 그것에 대해 물어 보면 내가 알아 차리면 그 질문에 대답 할 것이다 ...). 더 쉬운 방법은 단순히 std::getline()을 사용하여 줄의 꼬리를 읽고 거기에있는 것을 확인하는 것입니다.

std::istream& skipspace(std::istream& in) { 
    std::istreambuf_iterator<char> it(in), end; 
    std::find_if(it, end, [](char c){ return c != ' '; }); 
    return in; 
} 
// ... 
if ((in >> skipspace).peek() != '\n') { 
    // .... 
} 
0

당신은 문자를 들여다 할 필요가 없습니다 :

또 다른 대안은,의 말 skipspace하자, 자신의 조작을 만들고, 줄 바꿈에 대한 검사에 그 이전을 사용하는 것입니다. 당신은 std::string 대신 char[]의에 Student::studentName을 변경할 수있는 경우,

std::istream& operator>> (std::istream& is, Student& student) 
{ 
    std::string line; 
    if (!std::getline(is, line)) 
    { 
     std::cout << "Can't read student name" << std::endl; 
     return is; 
    } 

    std::istringstream iss(line); 
    std::string ignore; 
    std::getline(iss, ignore, '-'); 
    iss >> std::ws; 
    iss.getline(student.studentName, 75); 

    /* 
    read and store className if needed ... 

    if (!std::getline(is, line)) 
    { 
     std::cout << "Can't read class name" << std::endl; 
     return is; 
    } 

    std::istringstream iss2(line); 
    iss2.getline(student.className, ...); 
    */ 

    return is; 
} 

를 또는 : 내가 std::getline()를 사용을 중지하고 다음 구문 분석 std::istringstream를 사용, 당신을 위해 줄 바꿈을 처리 할 것

std::istream& operator>> (std::istream& is, Student& student) 
{ 
    std::string line; 
    if (!std::getline(is, line)) 
    { 
     std::cout << "Can't read student name" << std::endl; 
     return is; 
    } 

    std::istringstream iss(line); 
    std::string ignore; 
    std::getline(iss, ignore, '-'); 
    iss >> std::ws >> student.studentName; 

    /* 
    read and store className if needed ... 

    if (!std::getline(is, student.className)) 
    { 
     std::cout << "Can't read class name" << std::endl; 
     return is; 
    } 
    */ 

    return is; 
} 
+0

'C 스타일 배열'? 나는'is.peek() == ws'와 공백 뒤에 오는 것이 모두 공백 인'C 스타일 배열 '을 선호한다. –

+0

읽기/파싱에 C 스타일 배열을 사용하지 않는 것이 좋다. STL의 구문 분석 기능은'std :: string'을 선호합니다. 그러나 첫 번째 예제에서 볼 수 있듯이 파싱 결과는 적어도 최종 C 스타일 배열에 저장됩니다. –

관련 문제