C++不是我的首選語言。需要基本幫助解析C++中的字符串
我有一個包含這個文件:
e 225,370 35,75
我想E,225,370,35,相互分離75到一個char和int類型,但我有麻煩了。我嘗試了我在網上和我的C++書中找到的所有內容,但仍然無法正常工作。請幫忙。
我會更容易在Java中做這件事。
C++不是我的首選語言。需要基本幫助解析C++中的字符串
我有一個包含這個文件:
e 225,370 35,75
我想E,225,370,35,相互分離75到一個char和int類型,但我有麻煩了。我嘗試了我在網上和我的C++書中找到的所有內容,但仍然無法正常工作。請幫忙。
我會更容易在Java中做這件事。
#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;
}
假設你已經將數據讀入一個串...
你需要什麼?
strtok會比strchr更方便 – 2010-02-02 04:13:18
'strtok'不是線程安全的,但是,如果這是一個問題。 – greyfade 2010-02-02 04:41:08
#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();
我不確定這種行爲,因爲我不是C++程序員,但如果這只是忽略了文件中的逗號,我會感到驚訝。可以? – danben 2010-02-02 02:59:40
@danben:它可以,但默認情況下不會。即使大多數專用的C++程序員也不會觸及必要的庫部分以使其忽略逗號(您必須創建自定義的「ctype facet」,創建包含該「facet」的「locale」,然後將該「imbue」流'locale')。 – 2010-02-02 03:07:57
@danden,你說得對。我已更新我的解決方案。 – 2010-02-02 03:09:24
如果你有控制權的格式,這將是(略)更容易,如果你消除了逗號閱讀,只需輸入類似
è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];
[編輯:如果你是偏執還是真的需要驗證您的輸入,在這一點上,你可以檢查ignore1
和ignore2
包含逗號]
在大多數情況下,然而,數據可能相關的,所以你想讀一個完整的行成一個單一的結構(或類):
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));
不錯的一個。我通常搞亂了字符串的find和substr方法。 – StackedCrooked 2010-02-02 07:49:25
如果你想使用老式的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
這個很乾淨。雖然,一定要檢查'fscanf'的返回值是否爲5,以確保所有變量都被正確指定。 – dreamlax 2010-02-02 03:42:00
在這些情況下,我相信fscanf要優於C++的方式。 – StackedCrooked 2010-02-02 07:51:42
這個問題的答案是什麼?目前的分數是+4-3,而不是一個降價願意解釋爲什麼。 – 2010-02-03 01:19:10
使用增強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。
Boost庫可以在這裏找到:http://www.boost.org/users/download/ – Demi 2010-02-02 05:32:37
的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
告訴我們你有什麼。 – bmargulies 2010-02-02 02:56:37
謝謝你們。有時我首先學習Java,對我來說C++非常令人沮喪。 – 2010-02-02 03:19:47
儘管它有時會令人沮喪,但它有助於獲得一些並不總是像Java一樣直接捆綁的強大庫。想象一下,如果你所擁有的僅僅是核心語言而沒有圖書館,Java將會是多麼令人沮喪。 – joshperry 2010-02-02 03:23:16