使用分隔符 C++ 将字符串解析为整数
Parse string into integers using delimiter C++
我正在尝试制作一个调用率计算器,输入将按以下方式完成:hh:mm
在此之后,我想将该字符串解析为两个仅以“:”作为分隔符的整数。我在这里找到的这个解决方案似乎只适用于 space,但我希望分隔符是冒号,而不是 space。有没有办法做到这一点?
#include <iomanip>
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
int main() {
string input;
getline(cin, input);
istringstream is(input);
int hours, minutes;
is >> hours>> minutes;
cout << timmar << endl;
cout << minuter << endl;
}
将分隔符读入另一个变量。
char colon;
is >> hours >> colon >> minutes;
if (colon != ':') {
cout << "Incorrect delimiter: " << colon << '\n';
}
我不想使用默认分隔符,而是使用自定义操纵器来专门处理分隔符:
std::istream& colon(std::istream& in) {
if (in.peek() != ':' || std::isspace(in.ignore().peek())) {
in.setstate(std::ios_base::failbit);
}
return in;
}
// ...
int hours, minutes;
if (in >> hours >> colon >> minutes) {
// process the input
}
使用这个操纵器避免冒号附近的 spaces 被认为是有效的:正常的输入操作从跳过 space 开始。将分隔符简单地读入变量将允许在分隔符前面使用 spaces,并且还允许任何非 space 字符作为分隔符。在定界符之后直接继续阅读将再次允许 spaces 在定界符之后。使用上面的 colon
操纵符会将这两种情况都变成错误。 ...当然,您 总是 需要检查 after 阅读和 before 使用结果输入是否成功
解决同一问题的一种完全不同的方法是重新定义流的符号 whitespace。这里的想法是利用流的 std::locale
和 imbue()
一个 std::locale
,它考虑所需的分隔符,例如,:
作为唯一的 "whitespace"。下面是一个完整的例子来证明这个想法。它使用带有自定义 std::locale
的单独 std::istream
以避免更改 std::cin
的工作方式。但是,它仍然使用 std::cin
流缓冲区,即它从与 std::cin
.
相同的源读取
#include <algorithm>
#include <locale>
struct myctype_base {
std::ctype<char>::mask table[std::ctype<char>::table_size];
myctype_base(unsigned char c) {
table[c] |= std::ctype_base::space;
}
};
struct myctype
: private myctype_base
, std::ctype<char> {
public:
myctype(char delimiter)
: myctype_base(delimiter)
, std::ctype<char>(myctype_base::table) {
}
};
int main() {
std::locale loc(std::locale(), new myctype(':'));
std::istream in(std::cin.rdbuf());
in.imbue(loc);
int hours, minutes;
if (in >> hours >> minutes) {
std::cout << "read hours=" << hours << " minutes=" << minutes << "\n";
}
else {
std::cout << "failed to read input\n";
}
}
我正在尝试制作一个调用率计算器,输入将按以下方式完成:hh:mm
在此之后,我想将该字符串解析为两个仅以“:”作为分隔符的整数。我在这里找到的这个解决方案似乎只适用于 space,但我希望分隔符是冒号,而不是 space。有没有办法做到这一点?
#include <iomanip>
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
int main() {
string input;
getline(cin, input);
istringstream is(input);
int hours, minutes;
is >> hours>> minutes;
cout << timmar << endl;
cout << minuter << endl;
}
将分隔符读入另一个变量。
char colon;
is >> hours >> colon >> minutes;
if (colon != ':') {
cout << "Incorrect delimiter: " << colon << '\n';
}
我不想使用默认分隔符,而是使用自定义操纵器来专门处理分隔符:
std::istream& colon(std::istream& in) {
if (in.peek() != ':' || std::isspace(in.ignore().peek())) {
in.setstate(std::ios_base::failbit);
}
return in;
}
// ...
int hours, minutes;
if (in >> hours >> colon >> minutes) {
// process the input
}
使用这个操纵器避免冒号附近的 spaces 被认为是有效的:正常的输入操作从跳过 space 开始。将分隔符简单地读入变量将允许在分隔符前面使用 spaces,并且还允许任何非 space 字符作为分隔符。在定界符之后直接继续阅读将再次允许 spaces 在定界符之后。使用上面的 colon
操纵符会将这两种情况都变成错误。 ...当然,您 总是 需要检查 after 阅读和 before 使用结果输入是否成功
解决同一问题的一种完全不同的方法是重新定义流的符号 whitespace。这里的想法是利用流的 std::locale
和 imbue()
一个 std::locale
,它考虑所需的分隔符,例如,:
作为唯一的 "whitespace"。下面是一个完整的例子来证明这个想法。它使用带有自定义 std::locale
的单独 std::istream
以避免更改 std::cin
的工作方式。但是,它仍然使用 std::cin
流缓冲区,即它从与 std::cin
.
#include <algorithm>
#include <locale>
struct myctype_base {
std::ctype<char>::mask table[std::ctype<char>::table_size];
myctype_base(unsigned char c) {
table[c] |= std::ctype_base::space;
}
};
struct myctype
: private myctype_base
, std::ctype<char> {
public:
myctype(char delimiter)
: myctype_base(delimiter)
, std::ctype<char>(myctype_base::table) {
}
};
int main() {
std::locale loc(std::locale(), new myctype(':'));
std::istream in(std::cin.rdbuf());
in.imbue(loc);
int hours, minutes;
if (in >> hours >> minutes) {
std::cout << "read hours=" << hours << " minutes=" << minutes << "\n";
}
else {
std::cout << "failed to read input\n";
}
}