我有一个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"
如何避免此问题,并保证在我的连接字符中正确计算字符?
谢谢!
答案 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()
成员。