2010-02-02 7 views
14

C++은 내가 선호하는 언어가 아닙니다.C++에서 문자열 파싱에 대한 기본적인 도움이 필요합니다.

나는이 포함 된 파일이 있습니다

e 225,370 35,75 

나는 문자와의 int로 전자, 225, 370, 35, 서로 75를 분리하려는하지만 난 문제가 있어요. 나는 온라인에서 발견 한 모든 것을 C++ 책에서 시도했지만 여전히 효과가 없습니다. 도와주세요.

Java에서이 작업을 더 쉽게 할 수 있습니다.

+0

Here를 찾을 수 있습니다. – bmargulies

+0

감사합니다. C++은 자바를 처음으로 배웠을 때 나에게 매우 좌절 스럽습니다. –

+2

가끔은 좌절 할 수도 있지만, Java와 같이 항상 번들로 묶이지 않은 강력한 라이브러리를 확보하는 것이 도움이됩니다. 모든 것이 핵심 언어이고 라이브러리가 없다면 Java가 얼마나 좌절하는지 상상해보십시오. – joshperry

답변

-1
#include <iostream> 
#include <fstream> 

using namespace std; 

int main() 
{ 
     ifstream f("a.txt"); // check for errors. 

     char ch,dummy; 
     int i1,i2,i3,i4; 

     f>>ch>>i1>>dummy>>i2>>i3>>dummy>>i4; 

     cout<<ch<<endl<<i1<<endl<<i2<<endl<<i3<<endl<<i4<<endl; 

     return 0; 
} 
2

  1. strchr과는 String.index처럼 ... 당신은 문자열로 데이터를 읽은 것으로 가정.
  2. strtol 함수가있는 Integer.parseInt 같다()

당신은 다른 무엇이 필요합니까?

+1

strchr이 strchr보다 더 편리 할 것입니다. –

+0

'strtok'은 스레드 안전성을 보장하지 못합니다. – greyfade

2
#include <fstream> 

/* ... */ 

ifstream file; 
file.open("yourfile.txt"); 
char c, dummy; 
int i[4]; 
file >> c >> i[0] >> dummy >> i[1] >> i[2] >> dummy >> i[3]; 
file.close(); 
+0

저는 C++ 프로그래머가 아니기 때문에 그 행동에 대해 확신하지 못했습니다.하지만 파일에서 쉼표 만 무시하면 놀랄 것입니다. 그거야? – danben

+0

@ 단벤 : 가능하지만 기본적으로 그렇지는 않습니다. 대부분의 헌신적 인 C++ 프로그래머조차도 쉼표를 무시하는 데 필요한 라이브러리 부분을 절대 만지지 않습니다 (사용자 정의 'ctype 패싯'을 만들고 '패싯'을 포함하는 '로케일'을 만든 다음 스트림을 'imbue') 그 '로케일'). –

+0

@danden, 네가 맞아. 솔루션을 업데이트했습니다. –

4

당신은 형식을 제어 할 경우 수 있습니다 (약간) 쉽게 당신이 쉼표를 제거하는 경우, 읽고, 단지

전자처럼 입력을 가지고 225 (370) (35) (75)

이 형식을 사용하면 데이터를 읽는 Poita_ 코드는 [편집 : 코드를 업데이트하여 쉼표를 명시 적으로 읽거나 건너 뛰기 때문에] 작동합니다. 그렇지 않으면, 당신은 명시 적으로 쉼표 건너 뛸해야합니다 :

char ingore1, ignore2; 
char ch; 
int i[4]; 

file >> ch >> i[0] >> ignore1 >> i[1] >> i[2] >> ignore2 >> i[3]; 

[편집 : 당신이 정말 편집증 경우, 또는이 시점에서 당신이 ignore1ignore2 쉼표 포함되어 있는지 확인할 수 있습니다, 귀하의 의견을 확인해야합니다.] 단일 구조체 (또는 클래스)로 전체 라인을 읽고 싶은 것, 그래서 대부분의 경우

는하지만, 데이터가 아마 관련이 있습니다

struct data { 
    char ch; 
    int i[4]; 

    std::istream &operator>>(std::istream &is, data &d) { 
     char ignore1, ignore2; 
     return is >> ch >> i[0] >> ignore1 >> i[1] >> i[2] >> ignore2 >> i[3]; 
    } 
}; 

다 끝나면, 당신은 읽을 수 전체 data 한 번에 개체 :

std::ifstream infile("my data file.txt"); 
data d; 

infile >> d; 

또는 당신이이 가득 전체 파일이있는 경우, 당신은 벡터에 그들 모두를 읽을 수 있습니다

std::vector<data> d; 

std::copy(std::istream_iterator<data>(infile), 
    std::istream_iterator<data>(), 
    std::back_inserter(d)); 
+0

좋은 것. 나는 보통 string의 find 및 substr 메소드를 사용하고있다. – StackedCrooked

3

당신은 구식 C 런타임을 사용하려면

FILE * pf = fopen(filename, "r"); 
char e; 
int a, b, c, d; 
int ii = fscanf(pf, "%c %d,%d %d,%d", &e, &a, &b, &c, &d); 
if (ii < 5) 
    printf("problem in the input file"); 
fclose (pf); 

편집 : 덧글에 기반한 오류 검사 추가 드림 락

+1

이것은 매우 깨끗합니다. 그러나 모든 변수가 적절하게 할당되도록 'fscanf'의 반환 값이 5인지 확인해야합니다. – dreamlax

+1

이러한 상황에서 나는 fscanf가 C++보다 우월하다고 믿습니다. – StackedCrooked

+0

이 답변에 대한 모든 가격 인하 조치는 무엇입니까? 현재 점수는 +4 -3이며 이유를 설명하고자하는 단일 점수는 아닙니다. –

2

사용 문자열을 분할하려면 토큰 화를 부스트하십시오.

#include <iostream> 
#include <boost/tokenizer.hpp> 
#include <string> 
#include <vector> 

using namespace std; 

... 

typedef boost::tokenizer<boost::char_separator<char> > tokenizer; 

string teststring("e 225,370 35,75"); 
boost::char_separator<char> separators(", "); 
tokenizer tokens(teststring, separators); 
vector<string> substrings; 
for (tokenizer::iterator iter = tokens.begin(); iter != tokens.end(); ++iter) 
{ 
    substrings.push_back(*iter); 
} 

과, 짜잔, 당신은 깔끔한 벡터에서 문자열을 모두 가지고 : 나는 샘플 코드 뭔가 같은 것 때문에 첫 번째 토큰이, 숯불이라고 가정하고있다.char는 std :: string으로 substrings [0]에 있고, 다음 int 값은 부분 문자열 [1]과 그 뒤의 std :: string에 있습니다. 정수 값으로 변환해야합니다. 이를 위해 stringstream을 살펴 보시기 바랍니다.

+0

Boost 라이브러리는 다음에서 찾을 수 있습니다. http://www.boost.org/users/download/ – Demi

13

C++ String Toolkit Library (StrTk)이 문제에 대한 다음과 같은 솔루션이 있습니다

 
int main() 
{ 
    std::string data("e 225,370 35,75"); 
    char c1; 
    int i1,i2,i3,i4; 
    strtk::parse(data,", ",c1,i1,i2,i3,i4); 
    return 0; 
} 

더 많은 예제는 당신이 무엇을 우리에게

관련 문제