【问题标题】:C++ how to count correctly the characters in a const char?C++ 如何正确计算 const char 中的字符?
【发布时间】:2012-02-17 16:13:31
【问题描述】:

我有一个 const char,它是这样连接而成的:

const char *fileName = "background1";

std::stringstream sstm;
sstm << fileName << "-hd.png";
fileName = sstm.str().c_str();

我的问题是以下指令:

printf("const char = %s size = %d", fileName, sizeof(fileName));

返回:

"const char = background1-hd.png size = 4"

而我希望它会返回:

"const char = background1-hd.png size = 19"

例如,以下给出了方便的结果(因为没有连接):

const char *fileName2 = "background1-hd";
printf("const char = %s size = %d", fileName2, sizeof(fileName2));

返回:

"const char = background1-hd.png size = 19"

如何避免这个问题并保证在我的连接字符中正确计算字符?

谢谢!!

【问题讨论】:

  • c 标签已移除。我不懂C++,但我建议你使用std::string 而不是char *
  • 您最后的代码-sn-p 不会打印您所说的内容。你一定是在什么地方弄糊涂了。 (也许您实际上fileName2 声明为const char fileName2[] = "background1-hd"?)
  • 除了您的其他问题之外,此代码fileName = sstm.str().c_str(); 为您提供了一个指向临时字符串的指针,使其在语句末尾已经无效。

标签: c++ arrays char concatenation


【解决方案1】:

sizeof()返回变量在内存中占用的字节数(在本例中返回指针fileName的大小)。

strlen() 返回字符串的长度(这是你需要的)。

你也可以试试:

#include <iostream>
#include <cstdio>

int main()
{
    std::string fileName("background1");
    fileName.append("-hd.png");
    printf("const char = %s size = %d", fileName.c_str(), fileName.length());

    return 0;
}

【讨论】:

    【解决方案2】:

    sizeof 返回你给它的变量的大小;它在编译时进行评估。 “4”是系统上指针的大小。您想使用strlen() 来确定字符串的长度。

    【讨论】:

      【解决方案3】:

      sizeof(fileName) 的结果与 fileName 是指针而不是数组有关。它从字面上返回指向常量字符串的指针的大小,并且在 32 位系统上,所有指针都是 32 位(因此 sizeof == 4)。

      你应该改用strlen 或类似的,它将计算字符串中的字符,直到尾随的空值,并返回它。用strlen 代替sizeof 的结果将是您所期望的。

      与侧面相关,对于const char 字符串,每个“单元格”(实际上是字节)只有一个字符。有些字符集每个 character 包含多个 bytes,但是将多个字符打包成一个字节是非常罕见的,至少在 C 系列语言中是这样。

      【讨论】:

        【解决方案4】:

        sizeof 以字节为单位计算数据类型的大小,而不是其内容的大小(它指向的内容)。在您的示例中,您正在计算系统上的 4 个字节的 sizeof char*。要获取 C 字符串的长度,请使用 strlen

        【讨论】:

          【解决方案5】:

          在语言中数组和指针之间存在区别,即使这种区别似乎被隐式转换(数组很容易衰减成指针)和常见的声明 他们是一样的

          这与您的代码有什么关系?

          好吧,字符串文字实际上是一个由常量字符组成的数组,而不是一个指向字符的指针。在初始化const char *fileName = "background1"; 中,您正在创建一个 pointer 变量,该变量指向数组的第一个元素(“background1”衰减为指向第一个元素的指针),从那里你管理的变量是 pointer 而不是文字。

          如果您将此与 sizeof 会告诉您变量的大小这一事实相结合,您会在具有 32 位指针和 8 位字符的平台中得到它,sizeof( const char* ) 始终为 4,无论对象是什么由该指针指向(如果有的话)。

          现在,如果您将文字视为实际内容,那么您将获得更多的运气:

          const char filename[] = "background1";
          assert( sizeof filename == 12 );       // note: NUL character is counted!
          const char *fname = filename;
          assert( sizeof filename == sizeof( void* ) );
          

          在实际代码中,您并没有那么幸运,而且在很多情况下,在您有机会获得文字的编译时大小之前,文字已经衰减为指针,因此您不能要求编译器告诉您大小.在这种情况下,您需要计算 C 样式字符串的长度,这可以通过调用strlen 来完成。

          【讨论】:

            【解决方案6】:

            strlen 已被多次建议,对于这种情况,它可能是完全合理的。

            虽然有一个替代方案可以让您使用sizeof

            char fileName[] = "background1";
            
            std::cout << sizeof(fileName) << "\n";
            

            由于您将fileName 设为一个数组,因此它具有数组的所有特征——包括您稍后尝试分配给它的事实:

            fileName = sstm.str().c_str();
            

            ...会失败(当fileName 被定义为数组时甚至不会编译)。但是,我应该补充一点,在我看来,您最好始终使用std::string

            std::string fileName("background1");
            std::stringstream sstm;
            sstm << fileName << "-hd.png";
            fileName = sstm.str();
            

            在这种情况下,您可以使用字符串的size()length() 成员。

            【讨论】:

              猜你喜欢
              • 2019-03-25
              • 1970-01-01
              • 2019-09-10
              • 2011-02-17
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2018-07-12
              相关资源
              最近更新 更多