2010-02-02 101 views
14

C++不是我的首選語言。需要基本幫助解析C++中的字符串

我有一個包含這個文件:

e 225,370 35,75 

我想E,225,370,35,相互分離75到一個char和int類型,但我有麻煩了。我嘗試了我在網上和我的C++書中找到的所有內容,但仍然無法正常工作。請幫忙。

我會更容易在Java中做這件事。

+0

告訴我們你有什麼。 – bmargulies 2010-02-02 02:56:37

+0

謝謝你們。有時我首先學習Java,對我來說C++非常令人沮喪。 – 2010-02-02 03:19:47

+2

儘管它有時會令人沮喪,但它有助於獲得一些並不總是像Java一樣直接捆綁的強大庫。想象一下,如果你所擁有的僅僅是核心語言而沒有圖書館,Java將會是多麼令人沮喪。 – joshperry 2010-02-02 03:23:16

回答

-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

strtok會比strchr更方便 – 2010-02-02 04:13:18

+0

'strtok'不是線程安全的,但是,如果這是一個問題。 – greyfade 2010-02-02 04:41:08

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 2010-02-02 02:59:40

+0

@danben:它可以,但默認情況下不會。即使大多數專用的C++程序員也不會觸及必要的庫部分以使其忽略逗號(您必須創建自定義的「ctype facet」,創建包含該「facet」的「locale」,然後將該「imbue」流'locale')。 – 2010-02-02 03:07:57

+0

@danden,你說得對。我已更新我的解決方案。 – 2010-02-02 03:09:24

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

不錯的一個。我通常搞亂了字符串的find和substr方法。 – StackedCrooked 2010-02-02 07:49:25

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); 

編輯:添加基於評論的錯誤檢查dreamlax

+1

這個很乾淨。雖然,一定要檢查'fscanf'的返回值是否爲5,以確保所有變量都被正確指定。 – dreamlax 2010-02-02 03:42:00

+1

在這些情況下,我相信fscanf要優於C++的方式。 – StackedCrooked 2010-02-02 07:51:42

+0

這個問題的答案是什麼?目前的分數是+4-3,而不是一個降價願意解釋爲什麼。 – 2010-02-03 01:19:10

2

使用增強Tokenizer分割字符串。我假設只有第一個標記是一個字符,所以示例代碼會是這樣的:

#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在substrings [0]中作爲std :: string,以下int值在substrings [1]及其後面,也作爲std :: string。您將需要將它們轉換爲整數值。爲此,我建議你看看stringstream。

+0

Boost庫可以在這裏找到:http://www.boost.org/users/download/ – Demi 2010-02-02 05:32:37

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; 
} 

更多的例子可以發現Here