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

时间:2010-02-16 04:51:58

标签: c++ arrays string sizeof cout

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

我有一个名为'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个值。

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

我有点像C ++ newb,所以任何帮助都会受到赞赏。

8 个答案:

答案 0 :(得分:10)

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

作为旁注,使用标准库容器(例如,向量)可以解决此问题。

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

请记住sizeof 总是在编译时在C ++中进行评估,而不是在运行时。

答案 1 :(得分:8)

作为一个侧面评论,有更好的方法来检查数组的大小(对于数组在范围内并且没有衰减成指针的情况)是类型安全的:

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

答案 2 :(得分:3)

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

答案 3 :(得分:1)

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

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

答案 4 :(得分:1)

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

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

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

P.S。请注意,对于std :: string,对象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)

答案 5 :(得分:1)

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

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

答案 6 :(得分:0)

在String vector中使用size()方法

答案 7 :(得分:0)

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

指向C-Style字符串的指针数组

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

char数组 - 打包文本

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

std::string

的数组

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

摘要

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