我想在C++语言中以这种格式(x : y:z)输入数据。
在输入部分,输入的格式应该是这样的:
x : y : z
其中,x、y和z是三个独立的整数类型输入。
x : y : z
其中,x、y和z是三个独立的整数类型输入。
#include <iostream>
int main() {
int x, y, z;
char colon;
if (std::cin >> x >> colon >> y >> colon >> z) {
std::cout << "\nYou entered:\t" << x << "\t" << y << "\t" << z;
}
else {
std::cerr << "\nError: Wrong input format\n";
}
return 0;
}
if ((std::cin >> x >> colon) && (colon ==':') && (std::cin >> y >> colon) && (colon == ':') && (std::cin >> z)) {
虽然我认为没有人关心这个,但是为了完整起见...
对于一般情况。最好使用std::getline
来读取一行完整的输入,然后再进行分割。
这种任务永远不需要boost库。
以下是一些常见的字符串拆分模式:
将字符串拆分成标记是一项非常古老的任务。有许多解决方案可用。它们具有不同的属性。有些难以理解,有些难以开发,有些更复杂,速度可能更慢或更快、更灵活或不灵活。
其他选择
std::strtok
函数。可能不安全。也许不再应该使用。std::getline
。最常用的实现。但实际上是一种“滥用”,不太灵活。请参见一段代码中的4个示例。
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <regex>
#include <algorithm>
#include <iterator>
#include <cstring>
#include <forward_list>
#include <deque>
using Container = std::vector<std::string>;
std::regex delimiter{ "," };
int main() {
// Some function to print the contents of an STL container
auto print = [](const auto& container) -> void { std::copy(container.begin(), container.end(),
std::ostream_iterator<std::decay<decltype(*container.begin())>::type>(std::cout, " ")); std::cout << '\n'; };
// Example 1: Handcrafted -------------------------------------------------------------------------
{
// Our string that we want to split
std::string stringToSplit{ "aaa,bbb,ccc,ddd" };
Container c{};
// Search for comma, then take the part and add to the result
for (size_t i{ 0U }, startpos{ 0U }; i <= stringToSplit.size(); ++i) {
// So, if there is a comma or the end of the string
if ((stringToSplit[i] == ',') || (i == (stringToSplit.size()))) {
// Copy substring
c.push_back(stringToSplit.substr(startpos, i - startpos));
startpos = i + 1;
}
}
print(c);
}
// Example 2: Using very old strtok function ----------------------------------------------------------
{
// Our string that we want to split
std::string stringToSplit{ "aaa,bbb,ccc,ddd" };
Container c{};
// Split string into parts in a simple for loop
#pragma warning(suppress : 4996)
for (char* token = std::strtok(const_cast<char*>(stringToSplit.data()), ","); token != nullptr; token = std::strtok(nullptr, ",")) {
c.push_back(token);
}
print(c);
}
// Example 3: Very often used std::getline with additional istringstream ------------------------------------------------
{
// Our string that we want to split
std::string stringToSplit{ "aaa,bbb,ccc,ddd" };
Container c{};
// Put string in an std::istringstream
std::istringstream iss{ stringToSplit };
// Extract string parts in simple for loop
for (std::string part{}; std::getline(iss, part, ','); c.push_back(part))
;
print(c);
}
// Example 4: Most flexible iterator solution ------------------------------------------------
{
// Our string that we want to split
std::string stringToSplit{ "aaa,bbb,ccc,ddd" };
Container c(std::sregex_token_iterator(stringToSplit.begin(), stringToSplit.end(), delimiter, -1), {});
//
// Everything done already with range constructor. No additional code needed.
//
print(c);
// Works also with other containers in the same way
std::forward_list<std::string> c2(std::sregex_token_iterator(stringToSplit.begin(), stringToSplit.end(), delimiter, -1), {});
print(c2);
// And works with algorithms
std::deque<std::string> c3{};
std::copy(std::sregex_token_iterator(stringToSplit.begin(), stringToSplit.end(), delimiter, -1), {}, std::back_inserter(c3));
print(c3);
}
return 0;
}
#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("x:y:z");
boost::split(tokens, s, boost::is_any_of(":"));
// "x" == tokens[0]
// "y" == tokens[1]
// "z" == tokens[2]
return 0;
}