2012-11-17 70 views
0

我有下面的代碼,它使用strtok從txt文件接收輸入。在TXT文件中的輸入是:strtok或std :: istringstream

age, (4, years, 5, months) 
age, (8, years, 7, months) 
age, (4, years, 5, months) 

我的代碼如下所示:

char * point; 
ifstream file; 
file.open(file.c_str()); 

if(file.is_open()) 
{ 
    while(file.good()) 
    { 
     getline(file, take); 
     point = strtok(&take[0], ",()"); 
    } 
} 

它做精不同的是二次歲的輸出和第三年齡缺失。誰能告訴我他們爲什麼失蹤?

此外,我試圖istringstream但每當我輸入我的文件名程序崩潰。

char * point; 
char take[256]; 
ifstream file; 
file.open(file.c_str()); 

if(file.is_open()) 
{ 
    while(file.good()) 
    { 
     cin.getline(take, 256); 
     point =strtok(take,",()"); 
    } 
} 
+0

這是第二個代碼片段做什麼? – Xymostech

+0

我正在嘗試使用istringstream來做同樣的事情。但是我不知道爲什麼當輸入文件名時它崩潰了。 – user1823986

回答

5

就個人而言,我會用一個std::istringstream但我想不同的使用它(...,是的,我知道,我可以用sscanf()以及與該代碼會短一些,但我不喜歡的類型 - 不安全的界面)!我會玩與操縱器的技巧:

#include <iostream> 
#include <sstream> 
#include <string> 

template <char C> 
std::istream& skip(std::istream& in) 
{ 
    if ((in >> std::ws).peek() != std::char_traits<char>::to_int_type(C)) { 
     in.setstate(std::ios_base::failbit); 
    } 
    return in.ignore(); 
} 

std::istream& (*const comma)(std::istream&) = &skip<','>; 
std::istream& (*const open)(std::istream&) = &skip<'('>; 
std::istream& (*const close)(std::istream&) = &skip<')'>; 

struct token 
{ 
    token(std::string const& value): value_(value) {} 
    std::string::const_iterator begin() const { return this->value_.begin(); } 
    std::string::const_iterator end() const { return this->value_.end(); } 
    std::string value_; 
}; 

std::istream& operator>> (std::istream& in, token const& t) 
{ 
    std::istreambuf_iterator<char> it(in >> std::ws), end; 
    for (std::string::const_iterator sit(t.begin()), send(t.end()); 
     it != end && sit != send; ++it, ++sit) { 
     if (*it != *sit) { 
      in.setstate(std::ios_base::failbit); 
      break; 
     } 
    } 
    return in; 
} 

int main() 
{ 
    std::istringstream input("age, (4, years, 5, months)\n" 
          "age , (8 , years , 7, months)\n" 
          "age, (4, year, 5, months)\n" 
          "age, (4, years 5, months)\n" 
          "age (4, years, 5, months)\n" 
          "age, 4, years, 5, months)\n" 
          "age, (4, years, 5, months)\n"); 
    std::string dummy; 
    int   year, month; 
    for (std::string line; std::getline(input, line);) { 
     std::istringstream lin(line); 
     if (lin >> token("age") >> comma 
      >> open 
      >> year >> comma >> token("years") >> comma 
      >> month >> comma >> token("months") >> close) { 
      std::cout << "year=" << year << " month=" << month << "\n"; 
     } 
    } 
} 
+0

這看起來有點沉重,但非常完整。 – Xymostech

+1

@Xymostech:其中大部分是基礎架構,也可用於其他環境。也許是時候研究類似於'scanf()'的類型安全版本了,它建立在'std :: istream'上並使用可變參數... –

+0

+1對於操縱技巧。 'main'代碼看起來更具可讀性。 –