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

发布于 2024-08-21 05:35:44 字数 635 浏览 3 评论 0原文

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

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

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

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 个值。

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

我是一个 C++ 新手,所以任何帮助将不胜感激。

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.

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.

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.

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

离线来电— 2024-08-28 05:35:44

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

附带说明一下,使用标准库容器(例如矢量)可以缓解这种情况。

在您的 sizeof 示例中,sizeof(result) 正在询问指针的大小(可能是 std::string)。这是因为当传递给函数时,实际的数组类型会“衰减”为指向元素的指针类型(即使该函数被声明为采用数组类型)。 sizeof(result[0]) 返回数组中第一个元素的大小,巧合的是,它也是 16 个字节。在您的平台上,指针似乎是 16 字节(128 位)。

请记住,sizeof 在 C++ 中总是在编译时计算,而不是在运行时计算。

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

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

In your sizeof example, 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.

Remember that sizeof is always evaluated at compile-time in C++, never at run-time.

飘落散花 2024-08-28 05:35:44

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

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

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
}
蒲公英的约定 2024-08-28 05:35:44

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

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 are pointers 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.

我偏爱纯白色 2024-08-28 05:35:44

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

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

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.

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.

我也只是我 2024-08-28 05:35:44

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

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

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

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

使用向量数组的示例:

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

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.

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

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

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().

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)
捎一片雪花 2024-08-28 05:35:44
template< class T, size_t N >
std::size_t Length(const T(&)[N])
{
    return N;
};

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

std::cout << Length(another_array) << std::endl;
盛夏尉蓝 2024-08-28 05:35:44

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

In String vector use size() method

那小子欠揍 2024-08-28 05:35:44

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

指向 C 风格字符串的指针数组

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

char 数组 - 打包文本

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

std::string 数组

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

摘要

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

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

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 always a fixed size).

Array of char - packed text

Another method is to pass an array of char and 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.

Array of 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.

Summary

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文