Подтвердить что ты не робот

Как определить размер массива строк в С++?

Я пытаюсь просто распечатать значения, содержащиеся в массиве.

У меня есть массив строк, называемый "result". Я не знаю точно, насколько это велико, потому что он был автоматически сгенерирован.

Из того, что я прочитал, вы можете определить размер массива, выполнив следующее:

sizeof(result)/sizeof(result[0])

Это правильно? Потому что для моей программы sizeof (result) = 16 и sizeof (result [0]) = 16, так что код скажет мне, что мой массив имеет размер 1.

Однако это не выглядит правильным, потому что если я вручную распечатаю значения массива, например:

std::cout << result[0] << "\n";
std::cout << result[1] << "\n";
std::cout << result[2] << "\n";
std::cout << result[3] << "\n";
etc...

... тогда я вижу результирующие значения, которые я ищу. Массив имеет более 100 значений по длине/размеру.

Кажется, должно быть очень просто определить размер/длину массива... так что, надеюсь, я просто что-то пропустил здесь.

Я немного С++ newb, поэтому любая помощь будет оценена.

4b9b3361

Ответ 1

Вы не можете определить размер массива динамически в С++. Вы должны передать размер в качестве параметра.

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

В примере sizeof sizeof(result) запрашивает размер указателя (предположительно, std::string). Это связано с тем, что фактический тип массива "распадается" к типу "указатель-элемент" при передаче функции (даже если объявлена ​​функция для получения типа массива). sizeof(result[0]) возвращает размер первого элемента в вашем массиве, который по совпадению также равен 16 байтам. Похоже, что указатели имеют 16 байт (128 бит) на вашей платформе.

Помните, что sizeof всегда оценивается во время компиляции на С++, никогда во время выполнения.

Ответ 2

В качестве побочного комментария существуют лучшие способы проверки размера массива (для случаев, когда массив находится в области видимости и не разложился в указатель), которые являются типами:

// simple: runtime result
template <typename T, std::size_t N>
inline std::size_t sizeof_array( T (&)[N] ) {
   return N;
}

// complex: compile time constant
template <typename T, std::size_t N>
char (&static_sizeof_array( T(&)[N] ))[N];   // declared, not defined
#defined SIZEOF_ARRAY( x ) sizeof(static_sizeof_array(x))

В обоих случаях компилятор обнаружит, пытаетесь ли вы передать указатель (динамический массив или разложившийся массив):

void f( int array[] ) { // really: void f( int *array )
{
//   sizeof_array(array);              // compile time error
//   int another[SIZEOF_ARRAY(array)]; // compile time error
}
int main() {
   int array[] = { 1, 2, 3 };
   std::cout << sizeof_array(array) << std::endl; // prints 3
   int another_array[ SIZEOF_ARRAY(array) ];
   std::cout << sizeof_array(another_array) << std::endl; // 3 again
}

Ответ 3

Если у вас есть "реальный" массив, то работает трюк sizeof (x)/sizeof (x [0]). Если, однако, то, что у вас есть, действительно является указателем (например, что-то, возвращаемое функцией), тогда этот трюк не работает - вы в конечном итоге разделите размер указателя на sizeof указателя. Они представляют собой указатели на разные типы, но в обычной системе все указатели имеют одинаковый размер, поэтому вы их получите. Даже когда указатели имеют разные размеры, результат все равно не будет иметь никакого отношения к тому, сколько строк у вас есть.

Ответ 4

Лучше использовать std::vector<std::string> вместо необработанного массива. Тогда вам не нужно вручную управлять памятью массивов, и вы можете использовать метод size(), если хотите узнать количество элементов.

Если вы используете динамически выделенный необработанный массив, вы должны сами отслеживать его размер, размер не может быть получен из массива. Лучше всего сохранить его в дополнительной переменной.

Ответ 5

Элемент sizeof (array)/sizeof (element) работает для массивов фиксированной длины массивов с фиксированной длиной (не указателей). В качестве массива строк мы чаще всего используем (фиксированную длину) массив строк с указателями на разные (фиксированные) длины, чтобы этот трюк не работал. sizeof() используется для объектов, размер которых известен во время компиляции. Он не применим к динамически распределенным данным.

Когда объект содержит указатели, как в случае массива строк, sizeof() возвращает размер структуры самого высокого уровня (фиксированного размера). Часто это просто размер одного указателя. Он не включает размер выделенных данных, на которые указывают указатели. Поскольку эти данные фактически не являются частью основного объекта, это действительно один или несколько отдельных объектов (здесь вместо агрегата мы имеем агрегацию, см. http://en.wikipedia.org/wiki/Object_composition).

В С++ использование векторов очень удобно для ваших нужд. Можно использовать и другие подходящие стандартные контейнеры. length() и size() являются синонимами, см. http://www.cplusplus.com/reference/string/string/size/)

P.S. Обратите внимание, что для объекта std::string s sizeof (s) является константой, независимой от фактической (переменной) длины строки, возвращаемой s.length(). Фактически выделенный размер памяти возвращается s.capacity() и может быть больше длины().

Пример использования векторного массива:

#include <iostream>
#include <string>
#include <vector>

using namespace std;

int main()
{
    string s = "01234";
    cout << "s[" << s.length() << "]=\"" << s << "\"" << endl; 
    cout << "sizeof(s)=" << sizeof(s) << " (implementation dependent)" << endl;
    cout << endl;

    s += "56789012345";
    cout << "s[" << s.length() << "]=\"" << s << "\"" << endl; 
    cout << "sizeof(s)=" << sizeof(s) << " (implementation dependent)" << endl;
    cout << endl;

    vector<string>vs={"12","23","345","456","567","67888","7899999999","8","9876543210"};

    cout << "vs[" << vs.size() << "]={";
    size_t sz=0;
    for (size_t index=0; index<vs.size(); index++)
    {
        sz+=vs[index].size();
        if (index>0)
            cout << ",";
        cout << "\"" << vs[index] << "\":" << vs[index].size();
    }
    cout << "}:" << sz << endl;
    cout << "sizeof(vs)=" << sizeof(vs) << " (implementation dependent)" << endl;

    return 0;
}

Результат:

s[5]="01234"
sizeof(s)=8 (implementation dependent)

s[16]="0123456789012345"
sizeof(s)=8 (implementation dependent)

vs[9]={"12":2,"23":2,"345":3,"456":3,"567":3,"67888":5,"7899999999":10,"8":1,"9876543210":10}:39
sizeof(vs)=24 (implementation dependent)

Ответ 6

template< class T, size_t N >
std::size_t Length(const T(&)[N])
{
    return N;
};

std::cout << Length(another_array) << std::endl;

Ответ 7

В методе size() использования вектора строки

Ответ 8

Что-то, о чем нужно знать: текст может быть представлен различными способами. Массив текста также может быть представлен различными способами.

Массив указателей на строки C-Style

Общим методом является наличие массива указателей на char. Проблема в том, что размер массива не соответствует размеру всего текста. Кроме того, должно быть установлено право собственности на данные или указатель, поскольку текст, возможно, придется удалить (и может ли вызывающий удалить текст или вызвать вызывающего?). Поскольку это массив, размер массива должен всегда сопровождать массив во всех параметрах (если только массив всегда фиксированный размер).

Массив char - упакованный текст

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

Массив std::string

В С++ текст может быть представлен с помощью std::string. В этом случае массив представляет количество строк (аналогично массиву C-Strings выше). Чтобы получить общий размер всех строк, нужно суммировать размер каждой отдельной строки. Поскольку это массив, размер массива также должен быть передан.

Резюме

Во время выполнения массивы массивы должны сопровождать массив, когда массив передается. sizeof обрабатывается только во время компиляции. Более простая структура - std::vector, которая динамически обрабатывает распределение размера и памяти.