2

我有一个包含[51,53]. 我想将这些对分成两个整数。它们在 c_str 中,因为我从输入文件中读取它们。

必须有一种简单的方法来解析它们。我正在考虑使用该.at功能:。但我确信我让它变得复杂了。另外,它不起作用,因为它输出:

pair: 0x7ffffcfc2998
pair: 0x7ffffcfc2998 
etc
string pairstring = buffertm.c_str();
stringstream pair1, pair2;
int pairint1, pairint2;
pair1 << pairstring.at(1) << pairstring.at(2);
cout << "pair: " << pair1;
pair1 >> pairint1;
pair2 << pairstring.at(4) << pairstring.at(5);
//cout << "pair: " << pair2;
pair2 >> pairint2;

有没有更好的方法来做到这一点?

4

6 回答 6

5

像这样的东西:

char c1, c2, c3;
int first, second;

std::istringstream iss(str);

if (iss >> c1 >> first >> c2 >> second >> c3
    && c1 == '['  && c2 == ',' && c3 == ']' )
{
    // success
}

您可能需要额外检查一下右括号后是否还有更多字符:

if ((iss >> std::ws).peek() != EOF) {
   //^^^^^^^^^^^^^^
   // eats whitespace chars and returns reference to iss
   /* there are redundant charactes */
}
于 2013-11-06T15:13:23.223 回答
4

使用 C++11 试试这个std::stoi

char c_str[] = "[51,53]";
std::string s(c_str);
int num1 = std::stoi(s.substr(1, 2));
int num2 = std::stoi(s.substr(4, 2));

如果您知道数字将超出范围,请10-99改用:

char c_str[] = "[5156789,5]";
std::string s(c_str);
s.assign(s.substr(1, s.size() - 2));         // Trim away '[' and ']'
std::string::size_type middle = s.find(','); // Find position of ','
int num1 = std::stoi(s.substr(0, middle));
int num2 = std::stoi(s.substr(middle + 1, s.size() - (middle + 1)));

如果无法解析数字,该函数stoi将抛出。std::invalid_argument

编辑:

对于只会解析以 10 为底的数字的更强大的解决方案,您应该使用以下内容:

char c_str[] = "[51,0324]";

int num1, num2;
try {
    std::string s(c_str);
    s.assign(s.substr(1, s.size() - 2));
    std::string::size_type middle = s.find(',');

    std::unique_ptr<std::size_t> pos{new std::size_t};

    std::string numText1 = s.substr(0, middle);
    num1 = std::stoi(numText1, pos.get()); // Try parsing first number.
    if (*pos < numText1.size()) {
        throw std::invalid_argument{{numText1.at(*pos)}};
    }

    std::string numText2 = s.substr(middle + 1, s.size() - (middle + 1));
    num2 = std::stoi(numText2, pos.get()); // Try parsing second number.
    if (*pos < numText2.size()) {
        throw std::invalid_argument{{numText2.at(*pos)}};
    }
} catch (const std::invalid_argument& e) {
    std::cerr << "Could not parse number" << std::endl;
    std::exit(EXIT_FAILURE);
}

std::invalid_argument它会在尝试解析字符串时抛出"1337h4x0r",这与使用std::istringstream. 了解更多信息

于 2013-11-06T15:12:54.423 回答
3

出于多种原因,我建议采用两步过程,而不是一次尝试全部完成。

此外,其中一些在很大程度上取决于您可以安全地做出什么样的假设。

1)只是标记。如果您知道它将以“[”开头并且您知道将有一个逗号,并且您知道您只会得到两个数字,请在字符串中搜索“[”,然后使用 substr() 获取所有内容在它和逗号之间。那是一个令牌。然后从逗号到“]”做一些类似的事情来获得第二个标记。

2)一旦你有两个字符串,将它们转换为整数是相对简单的,并且有很多方法可以做到这一点。

在我打字时添加了一些答案,但我仍然建议采用两步法。

于 2013-11-06T15:18:15.860 回答
1

如果您对字符串的格式有足够的信心,您可以将整个内容放入 astringstream中,然后使用提取运算符;例如:

stringstream strm(pairstring);    
int pairint1 = 0, pairint2 = 0;
char c = 0;

strm >> c >> pairint1 >> c >> pairint2 >> c;

实际上,您也希望在其中进行一些错误检查,但希望这足以让您入门。

于 2013-11-06T15:10:23.510 回答
0

尝试使用strtok函数拆分字符串。对于转换使用atoi

于 2013-11-06T15:17:44.133 回答
0

我有一个包含 [51,53] 的 c_str

不,c_str()不是数据结构,它是一种方法,std::basic_string它返回一个常量 C 字符串,其数据与存储在std::string.

string pairstring = buffertm.c_str();比较麻烦,直接做string pairstring = buffertm;或使用即可buffertm

其次,你以错误的方式使用你的字符串流,你应该使用istringstream(在这里你将它用作ostringstream

int i, j;
istringstream iss(buffertm);
iss.get()
iss >> i;
iss.get()
iss >> j;
iss.get().
于 2013-11-06T15:21:34.747 回答