【问题标题】:How to print a row of an array?如何打印一行数组?
【发布时间】:2021-06-01 20:47:30
【问题描述】:

我对 C++ 编程还很陌生,我一直不知道如何从特定行打印值。

我的意思是:

std::string musical_things [][][] = {
    {
        {"Scale"}, {"Minor Natural"}, {"1","2","b3","4","5","b6","b7"}
    },
    {
        {"Scale"}, {"Major"}, {"1","2","3","4","5","6","7"}
    },

};

所以,当我尝试访问一个完整的行时,我得到了内存地址。 如果我循环它,我会得到每个元素的内存地址。

   for (int i = 0; i < 10; i++)
       std::cout << "Output: " << musical_things [i]<< "\n" << std::endl;

我只是想得到musical_things [i]。 对于 i = 0,输出应为:{"Scale"}, {"Chromatic"}, {"1","2","3","4","5","6","7"}

【问题讨论】:

  • 没有自动打印数组行的方法。您需要通过迭代各个元素来自己完成
  • 在您发布的代码中,您迭代最外层维度musical_things[i] 是一个二维数组。 musical_things[i][j] 是一维数组,其元素 musical_things[i][j][k] 是可以通过 std::cout &lt;&lt; 打印的字符串
  • 但是,您不应该在这里使用 3d 数组。它使事情变得不必要地复杂化。而是编写一个包含数据的结构并使用std::vector&lt;my_struct&gt;
  • 不幸的是,c++ 并不关心你想要什么。除了迭代单个字符串并打印它们之外,没有其他方法可以打印矩阵的行
  • "因为我将不得不重载 cout 运算符"不,这不是 std::vector 的缺点。您不能随意打印矢量,就像您不能随意打印数组一样。您的直接问题与向量完全相同,只是解决方案要容易得多

标签: c++ arrays for-loop multidimensional-array std


【解决方案1】:

ostreams 运算符 &lt;&lt; 没有重载,可以直接执行您想要的操作。您需要迭代字符串并打印它们:

for (int i = 0; i < 10; i++) {
  std::cout << "Output: ";
  for (int j = 0; j < 10; j++) {
      for (int k = 0; k < 10; k++) {
         std::cout << musical_things[i][j][k];
      }
      std::cout << "\n";
}

我假设所有尺寸的大小都是 10,但在您的示例中并非如此。管理多维 c 数组的大小是一团糟,您应该改用 std::vector,或者定义一个将数据保存在一起的结构。很有可能您实际上只需要一个维度 std::vector&lt;my_struct&gt;

【讨论】:

    【解决方案2】:

    请注意,您的数据不适合 3-D 数组模型:各个数组的长度不同,这会使编译器用零值字符“填充”它们。这是大量的填充,更糟糕的是,它不容易预测。

    例如,数据中最长的字符串有 13 个字符,因此所有字符串都将被填充到该大小(包括例如"1")。此外,最长的字符串列表包含 7 个字符串,因此所有列表都将填充到该大小。所以你的数组{"Scale"} 将被填充到一个包含 7 个字符串的数组中,其中的字符串包含 13 个零值字符。

    这真的不是你想要的。你可以忽略它(你真的不在乎编译器是否做了不必要的工作)但是当你尝试计算你的字符串时它会适得其反——你必须以某种方式忽略空字符串。

    假设您要解决此问题,请注意您的数据是 jagged array 字符串,而不是 3-D 数组。

    std::vector<std::vector<std::vector<std::string>>> musical_things =
    {
        {
            {"Scale"}, {"Minor Natural"}, {"1","2","b3","4","5","b6","b7"}
        },
        {
            {"Scale"}, {"Major"}, {"1","2","3","4","5","6","7"}
        },
    };
    

    为了制作打印它的代码,我决定使用自下而上的方法,这很容易解释。

    首先,我做了一个函数,它以你想要的格式打印一个字符串:

    void print(std::ostream& stream, const std::string& string)
    {
        stream << '"' << string << '"';
    }
    

    然后,我创建了一个打印字符串数组的函数:

    void print(std::ostream& stream, const std::vector<std::string>& array)
    {
        bool first_time = true;
        stream << '{';
        for (const std::string& s: array)
        {
            if (!first_time)
                stream << ",";
            print(stream, s);
            first_time = false;
        }
        stream << '}';
    }
    

    它遍历数组,并为每个字符串调用print 函数。它不能使用operator&lt;&lt;,因为您希望每个字符串都用引号引起来。

    它使用first_time 标志来正确打印分隔符 - 分隔符比字符串数少一个。


    最后,打印数组数组的代码:

    void print(std::ostream& stream, const std::vector<std::vector<std::string>>& array)
    {
        bool first_time = true;
        for (const auto& v: array)
        {
            if (!first_time)
                stream << ", ";
            print(stream, v);
            first_time = false;
        }
    }
    

    大体相同,只是使用了不同的分隔符,循环变量的类型是const auto&amp;,因为我懒得输入const std::vector&lt;std::string&gt;&amp;(我让编译器推断出来)。

    糟糕,我刚刚输入了!所以我其实并不懒:)

    【讨论】:

    • 哈哈,伙计,请给我一点时间仔细阅读您的回复,并尝试使其适用于我的程序。对我来说,这一次 C++ 太多了,哈哈哈。
    • 嘿伙计,很抱歉我花了这么多时间检查你的答案。这是我从编译器得到的错误:music_toolkit.cpp: In function 'void print(std::ostream&, const std::vector<:vector> > >& )': music_toolkit.cpp:11:23: 错误: 'const std::vector<:vector> > >&' 类型的引用的无效初始化类型的表达式const std::vector<:__cxx11::basic_string> >' print(stream, v);
    猜你喜欢
    • 1970-01-01
    • 2016-02-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-20
    • 2018-07-06
    • 1970-01-01
    • 2016-02-25
    相关资源
    最近更新 更多