Как распечатать строку массива?

#c #arrays #for-loop #multidimensional-array #std

#c #массивы #for-цикл #многомерный массив #ЗППП

Вопрос:

Я довольно новичок в программировании на 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"} .

Комментарии:

1. не существует автоматического способа печати строки массива. Вам нужно сделать это самостоятельно, повторяя отдельные элементы

2. в опубликованном вами коде, который вы повторяете, самым внешним измерением musical_things[i] является 2d-массив. musical_things[i][j] это одномерный массив, и его элементы musical_things[i][j][k] представляют собой строки, которые вы можете распечатать с помощью std::cout <<

3. однако здесь не следует использовать 3D-массив. Это делает ненужную компиляцию. Скорее напишите структуру, содержащую данные, и используйте std::vector<my_struct>

4. к сожалению, c не заботится о том, что вы хотите. Нет другого способа распечатать строку вашей матрицы, кроме перебора отдельных строк и их печати

5. «потому что мне придется перегрузить оператор cout » нет, это не недостаток std::vector . Вы не можете распечатать вектор так, как хотите, точно так же, как вы не можете распечатать массив так, как хотите. Ваша непосредственная проблема была бы точно такой же с вектором, просто решение оооочень намного проще

Ответ №1:

Для ostream оператора s нет перегрузки << , который делает то, что вы хотите напрямую. Вам нужно перебрать строки и распечатать их:

 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-массивов — это беспорядок, вместо этого вы должны использовать a std::vector или, скорее, определить структуру, которая содержит данные, которые принадлежат друг другу. Высока вероятность того, что вам действительно нужно только одномерное std::vector<my_struct> .

Ответ №2:

Обратите внимание, что ваши данные не соответствуют трехмерной модели массива: отдельные массивы имеют разную длину, что заставит компилятор «дополнить» их символами с нулевым значением. Это большое количество дополнений, и, что еще хуже, это нелегко предсказуемо.

Например, самая длинная строка в ваших данных содержит 13 символов, поэтому все строки будут дополнены до этого размера (включая, например "1" , ). Кроме того, самый длинный список строк содержит 7 строк, поэтому все списки будут дополнены до этого размера. Таким образом, ваш массив {"Scale"} будет дополнен массивом из 7 строк со строками, которые содержат 13 символов с нулевыми значениями.

Это действительно не то, что вы хотите. Вы можете игнорировать это (вам действительно все равно, выполняет ли компилятор ненужную работу), но это приведет к обратным результатам, когда вы попытаетесь сосчитать свои строки — вам придется каким-то образом игнорировать пустые строки.

Предполагая, что вы хотите это исправить, обратите внимание, что ваши данные представляют собой неровный массив строк, а не трехмерный массив.

 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::ostreamamp; stream, const std::stringamp; string)
{
    stream << '"' << string << '"';
}
 

Затем я создал функцию, которая печатает массив строк:

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

Он выполняет итерацию по массиву и вызывает print функцию для каждой строки. Он не может использоваться operator<< , потому что вы хотите, чтобы каждая строка была заключена в кавычки.

Он использует first_time флаг для правильной печати разделителей — на один разделитель меньше, чем количество строк.


Наконец, код, который печатает массив массивов:

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

Это в основном то же самое, но в нем используется другой разделитель, а тип переменной цикла — это const autoamp; , потому что мне было лень вводить const std::vector<std::string>amp; (я позволил компилятору вывести это).

Ой, я только что напечатал это! Так что я на самом деле не был ленивым 🙂

Комментарии:

1. Приятель, просто дай мне немного времени, чтобы внимательно прочитать твой ответ и попытаться заставить его работать в моей программе. Для меня это слишком много C сразу, хахаха.

2. Эй, приятель, извини за время, потраченное на проверку твоего ответа. Это ошибка, которую я получил от компилятора: musical_toolkit.cpp : В функции ‘void print(std::ostreamamp;, const std::vector<std::vector<std::__cxx11::basic_string<char> > >amp;)’: musical_toolkit.cpp:11:23: ошибка: недопустимая инициализация ссылки типа ‘const std::vector<std::vector<std::__cxx11::basic_string<char> > >amp;’ из выражения типа ‘const std::vector<std::__cxx11::basic_string<char> >’ print(поток, v);