2014-04-20 2 views
3

기본적으로 프로그램에서 조작 할 수 있도록 값을 읽지 않아도되는 텍스트 파일이 있습니다.텍스트 파일에서 데이터를 읽는 가장 좋은 방법 C++

전 C++을 사용하고 있으며 파일이 존재하는지 여부를 알기 위해 작업 코드를 작성했습니다.

텍스트 파일은 다음과 같이 포맷 :

1 7 
8 10 
20 6 
3 14 
... 

왼쪽에있는 값은 X 값과 오른쪽 값이 Y 값입니다입니다. (중간에있는 공백은 탭입니다.) 어떻게이 데이터를 추출합니까? 내가 바로 int로 문자열에서이를 변경 TryParse해야 클래스에서 사용하기 전에 ... 또한이 같은 클래스로

myVector(X,Y); 

그들을 통과 말할 것 같아요? C++은 이것을 할 수 있습니까?

감사합니다.

+0

TryParse는 C# -ism입니다. 여기서 C++로 프로그래밍 하시겠습니까? –

+0

루프에서 std :: getline. – lpapp

+0

그래, C# 백그라운드에서오고있어, 나는 그것을 거기에서 사용했다. 그러나 그것이 가능했는지에 관해 아는 것이 전혀 없었다. – Harvey

답변

6

내가 너라면이 글을 쓸 것입니다. 이것은 프로토 타입 코드 일 뿐이며 테스트조차되지 않았습니다.

근본적인 아이디어는 한 줄로 두 번 읽는 것이지만 다른 구분 기호로 읽는 것입니다. 먼저 탭 구분 기호로 읽은 다음 기본 줄 끝으로 읽습니다.

더 이상 읽을 것이 없으므로 루프를 정상적으로 종료해야하므로 파일이 "올 바르면"두 번째 파일로 충분할 수 있습니다.

벡터 클래스에서 예상하는 올바른 유형으로 변환해야합니다. 여기서 int라고 가정했으나 문자열이라면 내가 지정한 변환을 필요로하지 않습니다.

문법은 다음과 같이 읽을 수
qi::phrase_parse(begin, end, *(qi::int_ > qi::int_ > qi::eol), qi::ascii::blank, v); 

: "다음 하나 개 INT, 하나 개 INT, 다음 하나의 EOL 읽기 (끝

#include <string> 
#include <fstream> 

using namespace std; 

void yourFunction() 
{ 
    .. 
    ifstream myfile("myfile.txt"); 
    string xword, yword; 
    while (1) { 
     if (!getline(myfile, xword, '\t')) 
      break; 
     if (!getline(myfile, yword)) 
      break; 
     myVector.push_back(stoi(xword), stoi(yword)); 
    } 
    ... 
} 
+0

이것은 무엇을 찾고, 당신의 'if'진술을 exlain 수 있을까요? 어떤 일을하는지 잘 모르겠다. – Harvey

+0

@ user3012508 : 일단 모든 것을 읽으면 루프를 종료해야한다. 이론적으로 말해서, 두 번째 if 문은 파일이 "정확하다"면 충분할 수있다. – lpapp

+0

x와 y에서 실제로 어디에서 읽습니까? 그리고 저는 정말로 도움을 드리겠습니다. – Harvey

0

파싱 이런 종류의 boost.spirit 하나 개의 라인으로 수행 할 수 줄의 수) (\ n 또는 \ r \ n, 로캘에 따라 다름), 가능한 한 많은 시간 "으로 표시됩니다. int와 EOL 사이에는 공백 문자 (예 : 공백 또는 탭)가 있습니다.

장점 : std :: getline 루프보다는 코드가 더 명확하고 간결합니다. spirit.qi는 당신에게 더 강력한 통제권을 부여하고 당신은 스토이 콜을 필요로하지 않습니다. 단점 : 빌드 - 의존 (의존하지 않음) spirit.qi, 컴파일 시간.

#include <iostream> 
#include <fstream> 
#include <vector> 
#include <boost/spirit/include/qi.hpp> 
#include <boost/fusion/include/std_pair.hpp> 

namespace spirit = boost::spirit; 
namespace qi = spirit::qi; 

int main(int argc, char **argv) 
{ 
    std::ifstream in(argv[1], std::ios_base::in); 

    std::string storage; 
    in.unsetf(std::ios::skipws); 
    spirit::istream_iterator begin(in), end; 

    std::vector<std::pair<int, int> > v; 
    qi::phrase_parse(begin, end, *(qi::int_ > qi::int_ > qi::eol), qi::ascii::blank, v); 

    for(const auto& p : v) 
    std::cout << p.first << "," << p.second << std::endl; 

    return 0; 
}