简体   繁体   English

使用定界符C ++将字符串解析为整数

[英]Parse string into integers using delimiter C++

I am trying to make a callrate calculater where the input will be done as following: hh:mm 我试图做一个callrate计算器,其中输入将如下所示:hh:mm

After this i want to parse that string into two ints with only ':' as a delimiter. 在此之后,我想将该字符串解析为仅以':'为分隔符的两个整数。 This solution i got here seems to only work with space, but I want the delimiter to be colons, and not space. 我到这里的解决方案似乎只适用于空间,但是我希望定界符是冒号,而不是空间。 Is there even a possible way to do this? 甚至有可能这样做吗?

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

Read the delimiter character into another variable. 将分隔符读入另一个变量。

char colon;

is >> hours >> colon >> minutes;
if (colon != ':') {
    cout << "Incorrect delimiter: " << colon << '\n';
}

Instead of expecting a default delimiter I'd use a custom manipulator to specifically deal with the delimiter: 与其期望使用默认的定界符,不如使用自定义操纵器专门处理定界符:

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
}

Using this manipulator avoid spaces in the proximity of the colon being considered valid: the normal input operation start off with skipping space. 使用此操纵器可避免冒号附近的空格被视为有效:正常的输入操作从跳过空格开始。 Reading the delimiter simply into a variable would allow spaces in front of the delimiter and also allow any non-space character as a delimiter. 将分隔符简单地读入变量中将在分隔符前留有空格,并且还允许将任何非空格字符用作分隔符。 Carrying on reading directly after delimiter would, again, allow spaces after the delimiter. 再次在定界符后继续读取将再次在定界符后留空格。 Using the colon manipulator above turns both of these cases into an error. 上面使用colon操纵器会将这两种情况都变成错误。 ... and, of course, you always need to check after reading and before using the results whether input was successful. ...,当然,您始终需要阅读和使用结果之前检查输入是否成功。


An entirely different approach to the same problem is to redefine the stream's notation of whitespace . 解决同一问题的一种完全不同的方法是重新定义流的空白符号。 The idea here is to take advantage of the stream's std::locale and to imbue() a std::locale which considers the desired separator, eg, : as the only "whitespace". 这里的想法是利用流的std::locale并给imbue() std::locale imbue()一个考虑所需分隔符的std::locale ,例如, :是唯一的“空白”。 Below is a complete example demonstrating that idea. 下面是一个完整的示例,演示了该想法。 It uses a separate std::istream with a custom std::locale to avoid changing how std::cin works. 它使用带有自定义std::locale的单独std::istream来避免更改std::cin工作方式。 However, it still uses std::cin stream buffer, ie, it reads from the same source as 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";
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM