【问题标题】:C++ char array with stdin带有标准输入的 C++ 字符数组
【发布时间】:2010-09-27 12:30:52
【问题描述】:

我正在尝试获取由标准输入填充的数组的大小:

char *myArray;
cin >> myArray
cout << sizeof(myArray);

当我输入一个长度大于 4 的字符串时返回 4,例如"40905898"

我哪里错了?

【问题讨论】:

  • sizeof() 是一个编译器时间指令。在这种情况下,它将在编译时评估为一个固定的常量指针的大小。

标签: c++ arrays string pointers sizeof


【解决方案1】:

如果你打算使用 sizeof(myArray),你应该使用 sizeof(*myArray);因为使用指针,没有星号是地址而不是值。 像这样:

char *myArray;
cin >> *myArray;
cout << *myArray;

【讨论】:

    【解决方案2】:

    你这里似乎有很多问题:

    myArray 未初始化 - 输入将在哪里运行?

    你通常使用:cin >> myArray; (注意人字形和分号的方向)

    sizeof(myArray) 将始终返回相同的值(在您的平台上为 4)

    试试这个版本:

    char* myArray= new char[50];
    cin >> myArray;
    cout << myArray;
    cout << strlen(myArray);
    

    它不是没有自己的问题(我应该删除 myArray),所以你应该在这里尝试使用string myArray的答案

    【讨论】:

    • 嗯,没错——如果你调用一个函数,你会这样做。我在 main() 中对此进行了测试,所以它被清理了。
    【解决方案3】:

    sizeof 运算符静态评估您传递给它的东西的大小。 char* 是一个指针,根据机器架构,它具有特定的大小(32 位系统上为 4 个字节,64 位机器上为 8 个字节)。为了完成你想要做的事情,我建议你使用 string 类型,你可以通过将 #include &lt;string&gt;using namespace std; 添加到源文件中来使用它。

    string line;
    cin >> line;
    cout << line.length() << endl;
    

    它不易出错且更易于使用。

    顺便说一句,你试图做的事情真的很危险。实际上,当您使用cin &gt;&gt; myArray 时,您应该已经为myArray 分配了一些内存,而您还没有这样做。这将导致内存损坏,这可能会使您的程序崩溃并可能将其置于缓冲区溢出攻击中。

    C++ 中的简单数组不知道它的大小。你可以使用sizeof 只有当数组是静态分配的并且你在数组本身上使用sizeof,而不是另一个指向它的指针,例如这不会像你期望的那样工作:

    int x[5];
    int *a = &x[0];
    // a[i] is now the same as x[i] but:
    cout << sizeof(x) << endl; // prints 20, assuming int is 32 bits long
    cout << sizeof(a) << endl; // prints 4, assuming a pointer is 32 bits long
    

    请注意,数组的总大小打印在第一行,而不是元素计数。您可以使用sizeof(x)/sizeof(*x) 找出静态数组中的元素数。这对于使用new 的动态分配的数组是不可能的。事实上,C++ 数组非常容易出错,使用它们时应格外小心,大多数情况下最好使用 vectorstring

    【讨论】:

      【解决方案4】:

      正如其他人所说,sizeof 返回传递给它的对象的大小,在指针的情况下,它是指针的大小。 sizeof not 是否跟随指针来查看它所指向的对象的大小(它怎么知道它可以指向一个 char 或指向一个数组,没有好方法知道)。

      此外,当您从cin 读取数据时,您必须分配一些必须读取数据的空间,cin 不会为您分配空间。您可以在堆栈或堆上分配空间:

      char stack_line[1024]; // This will overflow if more than 1024 chars are needed
      char heap_line*  = new char[1024]; // ditto
      

      这里要注意的是 sizeof(stack_line) == 1024sizeof(heap_line) == 4 [在 32 位机器上] 所以在使用 sizeof 运算符时必须小心。

      在实践中,最好使用知道如何分配空间的std::string

      【讨论】:

        【解决方案5】:

        正如其他人所说,myArray 是一个指针。

        但是你为什么不使用std::string?您不需要自己进行缓冲区分配,您在示例中做错了(指针myArray 指向任何内容)

        std::string myValue;
        std::cin >> myValue;
        std::cout << myValue.length();
        

        如果需要,您可以使用string::c_str() 获取字符串的指针表示形式。

        【讨论】:

          【解决方案6】:

          这是因为您在指针上使用了 sizeof(),在您的 32 位计算机上是 4 个字节:

          printf("Pointer size: %d\n", sizeof(void*));
          

          如果您的数组是一个以 null 结尾的字符串(最后一个元素是零字节,或 '\0'),那么您可以使用

          strlen(myArray)
          

          获取元素的数量(减一)。例如:

          myArray = "Hello, world!";
          printf("Number of characters: %d\n", strlen(myArray));
          

          您也可以使用静态分配的数组,如下所示:

           char array[128];
           printf("sizeof(array) = %d\n", sizeof(array));
           // prints 128
          

          【讨论】:

            【解决方案7】:

            这是因为 myArray 是一个占用 4 个字节的指针。如果要获取字符串的长度,请使用 strlen 或类似的东西。

            【讨论】:

              【解决方案8】:

              sizeof(pointer) 将始终返回 4。您想使用 strlen()。

              编辑:IIRC,sizeof 在编译时评估,它只关心类型,而不关心内容。

              【讨论】:

              • 您假设是 32 位 CPU。在 64 位 CPU 上,它将返回 8。
              • @csl 如果您将其编译为 32 位,它将在 64 位 CPU 上返回 4 ;)
              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2016-05-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多