【问题标题】:print each char of string array with double pointer in C++在 C++ 中用双指针打印字符串数组的每个字符
【发布时间】:2021-11-07 10:00:09
【问题描述】:

程序应打印字符串数组的每个字符。

#include <iostream>
#include <string>

using namespace std;
int main()
{
    const char* numbers[10]{"One", "Too",   "Three", "Four", "Five",
                "Six", "Seven", "Eight", "Nine", "Zero"};

    /*  This version did not work. Why?
           for (const char** ptr = numbers; *ptr != nullptr; *ptr++) {
                const char* pos = *ptr;
                while (*pos != '\0')
                    cout << *(pos++) << " ";
            }
    */
    for(unsigned int i = 0; i < sizeof(numbers) / sizeof(numbers[0]); ++i)
    {
        const char* pos = numbers[i];
        while(*pos != '\0')
            printf("%c ", *(pos++));
        printf("\n");
    }
    return 0;
}

我知道我的代码是 C++17 和 C 的混合体(在从 C 到 C++ 的转换中,nullptrcout 是两个示例),但不确定第一个 for-loop

for (const char** ptr = numbers; *ptr != nullptr; *ptr++)

是否正确。它出什么问题了? 是否有“最佳实践”来循环遍历字符串数组(char 数组,还不是字符串对象),尤其是在这种情况下,我想捕获双指针?谢谢!

【问题讨论】:

  • 考虑将minimal reproducible example 放在一起,它实际上可以编译。
  • 谢谢!你真的很快!帖子已使用完整代码进行了编辑。
  • 数组有长度,它们不会以任何标记结束,例如 NULL 或类似的。自己添加适当的结束标记。
  • “双指针”这个词是模棱两可的,最准确的指类型double*。我建议改用“指向指针的指针”一词(正如pointer-to-pointer 标签描述所建议的那样)。
  • 我也在其他地方读过关于“指针到指针”的 cmets。我会尽量按照建议使用。

标签: c++ arrays char pointer-to-pointer


【解决方案1】:

两件事-

首先,在这个循环表达式中,您不需要在递增 ptr 后取消引用它 - *ptr++

for (const char** ptr = numbers; *ptr != nullptr; *ptr++)
                                                  ^^

*ptr++ 将被分组为 - *(ptr++),这意味着,(后)递增 ptr 并取消引用(后)递增的结果。它应该只是ptr++,因为在执行循环体之后,我们需要ptr 指针指向numbers 数组中的下一个元素。

其次,如果您的循环条件正在检查nullptr,那么循环正在迭代的数组应该有nullptr 作为指示数组结束的标记,您还需要增加数组的大小以调整结束标记:

     const char* numbers[11] {"One", "Too", "Three", "Four", "Five",
                              "Six", "Seven", "Eight", "Nine", "Zero", nullptr};

通过上述更改,以下循环应打印 numbers 数组字符串:

       for (const char** ptr = numbers; *ptr != nullptr; ptr++) {
           const char* pos = *ptr;

           while (*pos != '\0')
               cout << *(pos++) << " ";

           cout << "\n";
       }

由于您在numbers 数组中添加了一个新元素来标记数组的结尾,请小心,在第二个循环中,您正在执行sizeof(numbers)/sizeof(numbers[0]) 以获取数组大小,它将给出11 和第二个循环将最终访问nullptr,这将是未定义的行为。从sizeof 中减去1 导致循环条件,或者在处理之前添加检查pos != nullptr

【讨论】:

  • 非常感谢 ptr++ 的详细说明。我把你的作为答案。
【解决方案2】:

在你的第一个循环中,你在数组中寻找“nullptr”,但你没有把它放在那里。

您正在读取数组后未初始化的垃圾。

我建议使用 std::vector 或 std::array

【讨论】:

  • 感谢您指出 'nullptr' 不在数组中。向数组添加 NULL,for( const char** p2 = numbers; *p2 != NULL; *p2++) { ...} 仍然是段错误。
【解决方案3】:

尝试这些编辑,看看会发生什么

const char* numbers[11]{"One", "Too", "Three", "Four", "Five", 
                                    "Six", "Seven", "Eight", "Nine", "Zero", NULL};

;i < sizeof(numbers)/sizeof(numbers[0])-1;

在第二个for 循环中

基本上*ptr 指向相应字符串的开头。但是在最后一个之后,它就超出了界限。如果你真的要和nullptr比较的话,上面的方法就是这样做。

编辑

是的,除了上述之外,ptr 应该递增,而不是 *ptr*ptr 将遍历字符串而不是数组。

【讨论】:

  • 纯 C 部分正在工作。但我的问题是关于我正在努力解决的带有双指针的 for 循环部分。
  • @Yifangt 你试过编辑吗? sizeof 之后的 -1 不会改变任何东西。它在那里是因为现在数组中有 1 个额外的元素。
  • 是的,我为注释部分尝试了 -1。仍然是段错误。我认为问题出在 for 循环中的 *ptr++ 上,参见 H.S. 的回答。还是谢谢。
  • @Yifangt 是的,我错过了。此外,-1 不是用于注释循环,而是用于第二个循环
猜你喜欢
  • 2023-03-15
  • 1970-01-01
  • 2015-12-26
  • 1970-01-01
  • 1970-01-01
  • 2018-01-28
  • 1970-01-01
  • 2019-06-08
  • 1970-01-01
相关资源
最近更新 更多