2012-07-07 66 views
14

有什麼方法可以讀取像這樣的格式化字符串,例如:48754+7812=Abcs在C++中讀取格式化輸入的最簡單方法是?

比方說,我有三個stringz X,Y和Z,我想

X = 48754 
Y = 7812 
Z = Abcs 

兩個數字的大小和字符串可能會有所不同的長度,所以我不想使用substring()或任何像那樣。

是否有可能讓C++這樣

":#####..+####..=SSS.." 

,所以它知道直接發生了什麼參數?

回答

11

一種可能性是boost::split(),它允許多個定界符的說明書和不要求輸入的大小的先驗知識:

#include <iostream> 
#include <vector> 
#include <string> 

#include <boost/algorithm/string.hpp> 
#include <boost/algorithm/string/split.hpp> 

int main() 
{ 
    std::vector<std::string> tokens; 
    std::string s(":48754+7812=Abcs"); 
    boost::split(tokens, s, boost::is_any_of(":+=")); 

    // "48754" == tokens[0] 
    // "7812" == tokens[1] 
    // "Abcs" == tokens[2] 

    return 0; 
} 

或者,使用sscanf()

#include <iostream> 
#include <cstdio> 

int main() 
{ 
    const char* s = ":48754+7812=Abcs"; 
    int X, Y; 
    char Z[100]; 

    if (3 == std::sscanf(s, ":%d+%d=%99s", &X, &Y, Z)) 
    { 
     std::cout << "X=" << X << "\n"; 
     std::cout << "Y=" << Y << "\n"; 
     std::cout << "Z=" << Z << "\n"; 
    } 

    return 0; 
} 

然而,這裏的限制是必須在解析輸入之前決定字符串的最大長度(Z)。例如

+0

thanx很多的答案,但除了助推或任何外部庫之外,還有什麼其他東西.. 是否有可能在標準C++或至少stl – 2012-07-07 11:40:27

+0

@LoersAntario,更新的答案。 – hmjd 2012-07-07 11:43:42

+0

可以downvoter請解釋? – hmjd 2012-08-09 10:22:58

2


#include <boost/regex.hpp> 
#include <iostream> 

int main() 
{ 
    boost::regex re("\":(\\d+)\\+(\\d+)=(.+)\""); 
    std::string example = "\":48754+7812=Abcs\""; 
    boost::smatch match; 
    if (boost::regex_match(example, match, re)) 
    { 
     std::cout << "f number: " << match[1] << " s number: " << match[2] << " string: " << match[3] 
     << std::endl; 
    } 
    else 
    { 
     std::cout << "not match" << std::endl; 
    } 
} 

和第二個變體,只能使用字符串。

#include <string> 
#include <iostream> 

int main() 
{ 
    std::string s = "\":48754+7812=Abcs\""; 
    std::string::size_type idx = s.find(":"); 
    std::string::size_type end_first = s.find("+", idx + 1); 
    std::string f_number = s.substr(idx + 1, end_first - (idx + 1)); 
    std::cout << f_number << std::endl; 
    std::string::size_type end_second = s.find("=", end_first + 1); 
    std::string s_number = s.substr(end_first + 1, end_second - (end_first + 1)); 
    std::cout << s_number << std::endl; 
    std::string::size_type string_end = s.find("\"", end_second); 
    std::string str = s.substr(end_second + 1, string_end - (end_second + 1)); 
    std::cout << str << std::endl; 
} 
+0

用於提示正則表達式的+1 – 2012-07-07 11:41:32

+1

正則表達式在許多此類情況下都是一個很好的建議,+1。請注意,正則表達式支持在C++ 11中作爲C++的一部分提供 - 不需要再使用Boost正則表達式。 – jogojapan 2012-07-07 12:09:19

+1

@jogojapan不是現在=(http://liveworkspace.org/code/b66dcfa19ce7620fb7b9e4c203c42f43 – ForEveR 2012-07-07 13:16:52

11
#include <iostream> 
#include <sstream> 

int main(int argc, char **argv) { 
    std::string str = ":12341+414112=absca"; 
    std::stringstream ss(str); 
    int v1, v2; 
    char col, op, eq; 
    std::string var; 
    ss >> col >> v1 >> op >> v2 >> eq >> var; 
    std::cout << v1 << " " << v2 << " " << var << std::endl; 
    return 0; 
} 
+2

+1,因爲這是唯一正確考慮實際問題的答案,其他答案不會,因爲** 1 。使用boost並不是最簡單的方法**(我承認它可能是最精美的方式)和** 2。scanf不是C++風格**(正如相應答案的作者所述)。 – ChristophK 2015-11-03 11:25:54

3

您可以使用scanf。這是不是過於C++ - 十歲上下,但它確實在招用的代碼非常幾行:

char a[101], b[111], c[121]; 
sscanf(":48754+7812=Abcs", ":%100[^+]+%110[^=]=%120s", a, b, c); 
string sa(a), sb(b), sc(c); 
cout << sa << "-" << sb << "-" << sc << endl; 

的想法是指定由您閱讀使用非常有限的正則表達式語法字符串接受的人物。在這種情況下,第一個字符串被讀取到正號,第二個字符串被讀取到等號。

相關問題