gpt4 book ai didi

c++ - 字符串迭代器不在字符串末尾停止

转载 作者:行者123 更新时间:2023-12-02 10:22:31 25 4
gpt4 key购买 nike

我正在阅读由不同子字符串除以 ; 组成的行中的美味食谱按此顺序:

  • 配方索引 ( R1 )
  • 待煮数(1)
  • 配方名称 ( Ensalada Mixta )
  • 成分及其数量(Lechuga 200;...)

  • 前三个工作就像一个魅力,你可以看到它们存储在 data数组并打印在 printf堵塞。问题在于阅读其余部分。 reader迭代器完美地读取了该行,但不会在最后停止,因此它将垃圾值添加到该对并引发段错误。这是这个 MRE 的输出:
    :: R1
    :: 1
    :: Ensalada Mixta
    -> Lechuga 200
    -> Tomate 50
    -> Pepino 50
    -> Cebolla 50
    -> Aceite Oliva 5
    -> Vinagre De Vino 10
    -> Sal 1
    [1] 85313 segmentation fault (core dumped)

    循环应该在 Sal 1 之后停止,那我做错了什么?这是代码:

    #include <cmath>
    #include <list>
    #include <string>
    #include <utility>
    #include <cstdio>

    using namespace std;

    int main () {
    string line = "R1;1;Ensalada Mixta;Lechuga 200;Tomate 50;Pepino 50;Cebolla 50;Aceite Oliva 5;Vinagre De Vino 10;Sal 1";
    list<pair<string, unsigned> > ings;

    string recipe_data[3];
    string::const_iterator reader = line.cbegin();

    //Lectura del código, plato y ing_name de la receta
    for (int i = 0; i < 3; ++reader) {
    if (*reader != ';')
    recipe_data[i].push_back(*reader);
    else
    ++i;
    }

    printf(":: %s\n", recipe_data[0].c_str());
    printf(":: %s\n", recipe_data[1].c_str());
    printf(":: %s\n", recipe_data[2].c_str());
    /*
    * This is the problematic loop. The problem is in the while boolean
    * expression, which always evaluates to false.
    */
    while (reader != line.cend()) {
    string ing_name = "";
    unsigned ing_quantity = 0;

    while (*reader != ';' && reader != line.cend()) {
    ing_name += *reader;
    ++reader;
    }

    string::reverse_iterator it = ing_name.rbegin();

    for (int i = 0; *it != ' '; i++) {
    char c[1] = {*it};
    ing_quantity += atoi(c) * pow(10, i);
    ++it;
    ing_name.pop_back();
    }
    ing_name.pop_back();

    pair<string, unsigned> ing(ing_name, ing_quantity);
    ings.push_back(ing);

    printf("-> %s %d\n", ing.first.c_str(), ing.second);

    ++reader;
    }
    }

    这是在最后一个 ++reader 上使用断点的 gdb 输出线:
    Breakpoint 1, main () at so.cpp:52
    52 ++reader;
    1: reader = 59 ';'
    2: line.cend() = 0 '\000'
    3: ing = {first = "Tomate", second = 50}
    (gdb)
    Continuing.
    -> Pepino 50

    Breakpoint 1, main () at so.cpp:52
    52 ++reader;
    1: reader = 59 ';'
    2: line.cend() = 0 '\000'
    3: ing = {first = "Pepino", second = 50}
    (gdb)
    Continuing.
    -> Cebolla 50

    Breakpoint 1, main () at so.cpp:52
    52 ++reader;
    1: reader = 59 ';'
    2: line.cend() = 0 '\000'
    3: ing = {first = "Cebolla", second = 50}
    (gdb)
    Continuing.
    -> Aceite Oliva 5

    Breakpoint 1, main () at so.cpp:52
    52 ++reader;
    1: reader = 59 ';'
    2: line.cend() = 0 '\000'
    3: ing = {first = "Aceite Oliva", second = 5}
    (gdb)
    Continuing.
    -> Vinagre De Vino 10

    Breakpoint 1, main () at so.cpp:52
    52 ++reader;
    1: reader = 59 ';'
    2: line.cend() = 0 '\000'
    3: ing = {first = "Vinagre De Vino", second = 10}
    (gdb)
    Continuing.
    -> Sal 1

    Breakpoint 1, main () at so.cpp:52
    52 ++reader;
    1: reader = 0 '\000'
    2: line.cend() = 0 '\000'
    3: ing = {first = "Sal", second = 1}
    (gdb) n
    47 pair<string, unsigned> ing(ing_name, ing_quantity);
    1: reader = 0 '\000'
    2: line.cend() = 0 '\000'
    3: ing = {first = "Sal", second = 1}
    (gdb)
    29 string ing_name = "";
    1: reader = 0 '\000'
    2: line.cend() = 0 '\000'
    3: ing = {first = "Sal", second = 1}
    (gdb)
    28 while (reader != line.cend()) {
    1: reader = 0 '\000'
    2: line.cend() = 0 '\000'
    (gdb)
    29 string ing_name = "";
    1: reader = 0 '\000'
    2: line.cend() = 0 '\000'
    3: ing = {first = "Sal", second = 1}

    如您所见,它不应该重新进入循环,因为迭代器和 cend()是平等的,对吧?

    最佳答案

    内部 while 递增,直到找到 ;cend在这两种情况下你都继续。只有在下一次迭代中,您才会停止,因为 reader != line.cend()false但那已经太晚了。

    此外,您必须先检查您是否在最后,然后才能取消引用 reader :

        while (reader != line.cend() && *reader != ';') {
    ing_name += *reader;
    ++reader;
    }
    if (reader == line.cend()) break;

    关于c++ - 字符串迭代器不在字符串末尾停止,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59504886/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com