2014-12-02 83 views
1

我的代碼張貼如下。我希望能夠使用分隔符「()」進行解析,並將字符串轉換爲cpp中的整數。我很困惑如何解析多個分隔符在C++中使用getline和strtok

while(getline(fin, line)) 
{ 
    x = atoi((strtok(line.c_str(),'(,)')); 
    xx = atoi((strtok(NULL,"(),")); 
    xxx = atoi((strtok(NULL,"(),"))); 
    cout << x << " " << xx << " " << xxx << "\n"; 
} 

但由於某種原因,我得到以下錯誤

GraphTest.cpp:134:錯誤:從 '爲const char *' 到 '字符*'

GraphTest.cpp無效的轉換:134 :錯誤:初始化參數1'char * strtok(char *,const char *)'

.c_str應該將我的字符串轉換爲ac類型字符串,以允許我使用atoi和strtok函數。我很困惑,並會感謝任何幫助。

+0

看起來像你有一個不平凡的語法。選擇合適的工具來進行分析和解析(例如:flex +野牛或助推精神,......)。 – 2014-12-02 12:37:33

+0

''(,)''是錯誤的。它應該是'「(,)」'。 – 2014-12-02 12:37:34

+1

'c_str()'返回一個'const char *',它應該是一個不可修改的指向字符串內部緩衝區的指針。 'strotok()'**修改**輸入字符串以執行標記化(這就是爲什麼它接受'char *'而不是'const char *'),那麼就不應該這樣做。 – 2014-12-02 12:39:36

回答

0

它不編譯,因爲c_str()返回一個const char*,它應該是一個不可修改內部string緩衝區的常量指針。另一方面strtok()接受char*,因爲它修改了它的輸入字符串。

現在您有兩種選擇:從strtok()獲取可用的C字符串或將所有內容都重寫爲C++。

創建一個從你的C++字符串的新修改的C字符串:

char* modifiableLine = strdup(line.c_str()); 

x = atoi((strtok(modifiableLine, "(,)")); 
// Other processing 

free(modifiableLine); 

如果你必須保持包裝的C++函數/類中的C代碼量你可以做到這一點。更好的解決方案是使用C++標準庫提供的功能(如果C++ 11也使用C函數,則可以使用atoi() C函數)。讓我們先寫一個輔助函數:

int readNextInt(istringstream& is, const string& delimiters) { 
    string token; 

    if (getline(is, token, delimiters)) 
     return stoi(token); 

    return 0; // End of stream? 
} 

像這樣來使用:

istringstream is(line) 
x = readNextInt(is, "(),"); 
xx = readNextInt(is, "(),"); 
xxx = readNextInt(is, "(),"); 

請注意,標準的C++函數getline()不接受分隔符參數string但單一的char只有那麼你必須編寫你自己的重載版本。看看this post以獲得良好和可能的實現(您也可以在is.imbue()之後簡單替換getline()is >> token,參見給出的示例)。

那麼......如果您已經在使用Boost,那麼您可以簡單地使用boost::tokenizer

0

我有一個類似的問題需要與多個分隔符解析,並找不到一個好的解決方案,所以我最終只是一個功能。

string getlineMultDelimiter(istream &is, string dlm, bool includeDelimiter) 
{ 
    string str; 
    char c; 
    bool found = false; 

    while (!found && is) 
    { 
     for (size_t i = 0; i < dlm.length() && !found; ++i) 
      found = dlm[i] == is.peek(); 

     if (!found || includeDelimiter) 
     { 
      is.get(c); 
      str += c; 
     } 
    } 
    return str; 
} 

它會使用所有字符的字符串DLM作爲分隔符,你可以選擇是否包括在返回字符串中分隔符與否。