C++ 如何确定C++中字符串数组的大小?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2270726/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 22:48:12  来源:igfitidea点击:

How to determine the size of an array of strings in C++?

c++arraysstringsizeofcout

提问by Jake Wilson

I'm trying to simply print out the values contained in an array.

我试图简单地打印出数组中包含的值。

I have an array of strings called 'result'. I don't know exactly how big it is because it was automatically generated.

我有一个名为“result”的字符串数组。我不知道它到底有多大,因为它是自动生成的。

From what I've read, you can determine the size of an array by doing this:

根据我的阅读,您可以通过执行以下操作来确定数组的大小:

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

Is this correct? Because for my program, sizeof(result) = 16 and sizeof(result[0]) = 16 so that code would tell me that my array is of size 1.

这样对吗?因为对于我的程序, sizeof(result) = 16 和 sizeof(result[0]) = 16 这样代码就会告诉我我的数组的大小为 1。

However that doesn't appear correct, because if I manually print out the array values like this:

但是,这似乎不正确,因为如果我手动打印出这样的数组值:

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

...then I see the resulting values I'm looking for. The array is upwards of 100+ values in length/size.

...然后我看到了我正在寻找的结果值。该数组的长度/大小超过 100 个值。

It seems like it should be very simple to determine the size/length of an array... so hopefully I'm just missing something here.

确定数组的大小/长度似乎应该非常简单......所以希望我在这里遗漏了一些东西。

I'm a bit of a C++ newb so any help would be appreciated.

我有点 C++ 新手,所以任何帮助将不胜感激。

采纳答案by Jake Wilson

You cannot determine the size of an array dynamically in C++. You must pass the size around as a parameter.

您无法在 C++ 中动态确定数组的大小。您必须将大小作为参数传递。

As a side note, using a Standard Library container (e.g., vector) allieviates this.

作为旁注,使用标准库容器(例如,向量)可以缓解这种情况。

In your sizeofexample, sizeof(result)is asking for the size of a pointer (to presumably a std::string). This is because the actual array type "decays" to a pointer-to-element type when passed to a function (even if the function is declared to take an array type). The sizeof(result[0])returns the size of the first element in your array, which coincidentally is also 16 bytes. It appears that pointers are 16 bytes (128-bit) on your platform.

在您的sizeof示例中,sizeof(result)要求提供指针的大小(大概是 std::string)。这是因为实际的数组类型在传递给函数时会“衰减”为元素指针类型(即使函数被声明为采用数组类型)。在sizeof(result[0])您的阵列,这巧合也是16个字节在返回第一个元件的尺寸。在您的平台上,指针似乎是 16 字节(128 位)。

Remember that sizeofis alwaysevaluated at compile-time in C++, never at run-time.

请记住,sizeof始终在编译时在C ++进行评估,从来没有在运行时。

回答by David Rodríguez - dribeas

As a side comment, there are better ways of checking the size of an array (for the cases where the array is in scope and has not decayed into a pointer) that are typesafe:

作为旁注,有更好的方法来检查类型安全的数组大小(对于数组在范围内并且没有衰减为指针的情况):

// 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))

In both cases the compiler will detect if you try to pass in a pointer (dynamic array or decayed array):

在这两种情况下,编译器都会检测您是否尝试传入指针(动态数组或衰减数组):

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
}

回答by Jerry Coffin

If what you have is a "real" array, then the sizeof(x)/sizeof(x[0]) trick works. If, however, what you have is really a pointer(e.g. something returned from a function) then that trick doesn't work -- you'll end up dividing the size of a pointer by the sizeof a pointer. They arepointers to different types, but on a typical system all pointers are the same size, so you'll get one. Even when the pointers are different sizes, the result still won't have anything to do with how many strings you have.

如果您拥有的是“真实”数组,则 sizeof(x)/sizeof(x[0]) 技巧有效。但是,如果您所拥有的实际上是一个指针(例如从函数返回的某些内容),那么该技巧将不起作用——您最终将用指针的大小除以指针的大小。它们指向不同类型的指针,但在典型系统上,所有指针的大小都相同,因此您会得到一个。即使指针大小不同,结果仍然与您拥有的字符串数量无关。

回答by sth

Better use std::vector<std::string>instead of a raw array. Then you don't have to manually manage the arrays memory and you can use the size()method if you want to know the number of elements.

更好地使用std::vector<std::string>而不是原始数组。那么你就不必手动管理数组内存,size()如果你想知道元素的数量,你可以使用该方法。

If you use a dynamically allocated raw array you are expected to keep track of its size yourself, the size cannot be obtained from the array. Best save it in an extra variable.

如果您使用动态分配的原始数组,您需要自己跟踪其大小,则无法从数组中获取大小。最好将它保存在一个额外的变量中。

回答by d.nedelchev

The sizeof(array)/sizeof(element) works for fixed-length-array of fixed-length-arrays (not of pointers). As an array of strings we most often use a (fixed-length-)array of pointers-to-various-(fixed-)length-strings so this trick wouldn't work. sizeof() is used for objects which size is known at compile time. It's not applicable to dynamically allocated data itself.

sizeof(array)/sizeof(element) 适用于固定长度数组(不是指针)的固定长度数组。作为字符串数组,我们最常使用指向各种(固定)长度字符串的指针的(固定长度)数组,因此这个技巧不起作用。sizeof() 用于在编译时已知大小的对象。它不适用于动态分配的数据本身。

When an object contains pointers like in the case of an array of strings, sizeof() returns the size of the highest-level (fixed-size) structure. Often it's just the size of a single pointer. It does not include the size of the allocated data pointed to by the pointers. Because that data actually is not part of the main object, it's indeed one or more separate objects (we have aggregation here instead of composition, see http://en.wikipedia.org/wiki/Object_composition).

当对象包含像字符串数组那样的指针时,sizeof() 返回最高级别(固定大小)结构的大小。通常它只是单个指针的大小。它不包括指针指向的已分配数据的大小。因为该数据实际上不是主要对象的一部分,它确实是一个或多个单独的对象(我们在这里使用聚合而不是组合,请参阅http://en.wikipedia.org/wiki/Object_composition)。

In C++ using vectors is very convenient for your needs. Other suitable standard containers could be used too. length() and size() methods are synonyms, see http://www.cplusplus.com/reference/string/string/size/)

在 C++ 中,使用向量非常方便您的需要。也可以使用其他合适的标准容器。length() 和 size() 方法是同义词,参见http://www.cplusplus.com/reference/string/string/size/

P.S. Please note that for std::string s object sizeof(s) is a constant independent of the actual (variable) string length returned by s.length(). The actual allocated memory size is returned by s.capacity() and could be greater than length().

PS 请注意,对于 std::string s object sizeof(s) 是一个常量,独立于 s.length() 返回的实际(可变)字符串长度。实际分配的内存大小由 s.capacity() 返回,并且可能大于 length()。

Example using vector array:

使用向量数组的示例:

#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;
}

Result:

结果:

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)

回答by Joseph

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

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

回答by Thomas Matthews

Something to be aware of: text can be represented in different methods. An array of text can also be represented in different methods.

需要注意的是:文本可以用不同的方法表示。文本数组也可以用不同的方法表示。

Array of pointers to C-Style strings

指向 C 样式字符串的指针数组

A common method is to have an array of pointers to char. The issue is that the size of the array doesn't represent the size of all of the text. Also, the ownership of the data or pointer must also be established, as the text may have to be delete (and can the callee delete the text or does the caller?). Because it is an array, the size of the array must always accompany the array in all parameters (unless the array is alwaysa fixed size).

一个常见的方法是拥有一个指向 的指针数组char。问题是数组的大小并不代表所有文本的大小。此外,还必须建立数据或指针的所有权,因为可能必须删除文本(被调用者可以删除文本还是调用者可以删除文本?)。因为是数组,所以在所有参数中必须始终伴随数组的大小(除非数组始终是固定大小)。

Array of char- packed text

char- 打包文本数组

Another method is to pass an array of charand have the strings contiguous in the array. One string follows the termination char of the previous. With this array, the total size of all of the strings is represented, no wasted space. Again, with arrays, the size of the array must accompany the array when passed around.

另一种方法是传递一个数组char并使字符串在数组中连续。一个字符串跟在前一个字符串的终止符之后。使用这个数组,表示所有字符串的总大小,没有浪费空间。同样,对于数组,数组的大小在传递时必须伴随数组。

Array of std::string

数组 std::string

In C++, text can be represented using std::string. In this case, the array represents the quantity of strings (similar to the array of C-Strings above). To get the total size of all the strings, one must sum up the size of each individual string. Since this is an array, the size of the array must be passed also.

在 C++ 中,文本可以使用std::string. 在这种情况下,数组表示字符串的数量(类似于上面的 C-Strings 数组)。要获得所有字符串的总大小,必须将每个单独字符串的大小相加。由于这是一个数组,因此还必须传递数组的大小。

Summary

概括

During run-time array sizes must accompany the array when the array is passed around. sizeofis only processed at compile time. A simpler structure is std::vector, which handles size and memory allocation dynamically.

在运行时,当数组被传递时,数组大小必须伴随数组。 sizeof仅在编译时处理。一个更简单的结构是std::vector,它动态处理大小和内存分配。

回答by Thomas Matthews

In String vector use size() method

在字符串向量中使用 size() 方法