C ++如何正确计算const char中的字符?

时间:2012-02-17 16:13:32

标签: c++ arrays char concatenation

我有一个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"

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

谢谢!

6 个答案:

答案 0 :(得分:8)

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

答案 1 :(得分:3)

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

答案 2 :(得分:2)

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

你应该使用的是strlen或类似的,它将计算字符串中的字符,直到尾随空值,然后返回。以strlen代替sizeof的结果将与您的预期相符。

与边相关,const char个字符串每个“单元格”(实际为字节)只有一个字符。有一些字符集可以为每个字符创建多个字节,但是将多个字符打包成一个字节是非常罕见的,至少在C系列语言中是这样。

答案 3 :(得分:2)

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

答案 4 :(得分:1)

数组和指针之间的语言有所不同,即使这种区别似乎被隐式转换(数组倾向于衰减非常容易地转化为指针)所稀释,以及的常见语句它们是相同的

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

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

如果你把它与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来完成。

答案 5 :(得分:1)

已经多次提出

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()成员。