我正在尝试将图像读入char数组。这是我的尝试:
ifstream file ("htdocs/image.png", ios::in | ios::binary | ios::ate);
ifstream::pos_type fileSize;
char* fileContents;
if(file.is_open())
{
fileSize = file.tellg();
fileContents = new char[fileSize];
file.seekg(0, ios::beg);
if(!file.read(fileContents, fileSize))
{
cout << "fail to read" << endl;
}
file.close();
cout << "size: " << fileSize << endl;
cout << "sizeof: " << sizeof(fileContents) << endl;
cout << "length: " << strlen(fileContents) << endl;
cout << "random: " << fileContents[55] << endl;
cout << fileContents << endl;
}
这是输出:
size: 1944
sizeof: 8
length: 8
random: ?
?PNG
任何人都可以向我解释这个吗? 8位是否有文件结尾的字符?此示例取自cplusplus.com
运行Mac OS X并使用XCode进行编译。
答案 0 :(得分:10)
返回文件的大小。 image.png
的尺寸为1944 bytes
。
cout << "size: " << fileSize << endl;
返回您环境中sizeof(char*)
8
。 请注意,任何指针的大小在任何环境中始终相同。
cout << "sizeof: " << sizeof(fileContents) << endl;
您正在阅读的文件是二进制文件,因此它可能包含0
作为有效数据。当您使用strlen
时,它会返回长度,直到遇到0
,如果您的文件为8
,则会返回。
cout << "length: " << strlen(fileContents) << endl;
从文件开头返回56th location
处的字符(记住数组索引从0开始)。
cout << "random: " << fileContents[55] << endl;
建议:
请记得使用以下内容取消分配fileContents
的动态内存分配:
delete[] fileContents;
如果不这样做,您最终会创建 内存泄漏 。
答案 1 :(得分:3)
This answer我的另一个问题应该是您正在寻找的内容(尤其是关于将其读入vector<char>
的第二部分,您应该更喜欢这个数组。
至于你的输出:
sizeof(fileContents)
返回char *
的大小,系统为8(我猜是64位)strlen
在第一个'\0'
处停止,就像输出操作符一样。答案 2 :(得分:3)
fileSize - 文件中的字节数。
sizeof(fileContents) - 返回char *指针的大小。
strlen(fileContents) - 计算字符数,直到找到值为“0”的字符。这显然只是在8个字符之后 - 因为你正在阅读BINARY数据,这不是一个意想不到的结果。
cout&lt;&lt; fileContents - 就像strlen一样,cout写出字符,直到找到一个值为'0'的字符。从输出看起来有些字符不可打印。
您的示例还有其他一些问题 - 例如,它不释放所使用的内存。这是一个稍微强大的版本:
vector< char > fileContents;
{
ifstream file("htdocs/image.png", ios::in | ios::binary | ios::ate);
if(!file.is_open())
throw runtime_error("couldn't open htdocs/image.png");
fileContents.resize(file.tellg());
file.seekg(0, ios::beg);
if(!file.read(&fileContents[ 0 ], fileContents.size()))
throw runtime_error("failed to read from htdocs/image.png");
}
cout << "size: " << fileContents.size() << endl;
cout << "data:" << endl;
for( unsigned i = 0; i != fileContents.size(); ++i )
{
if( i % 65 == 0 )
cout << L"\n';
cout << fileContents[ i ];
}
答案 3 :(得分:2)
你期待什么? png文件是二进制文件,因此它们可能包含'\0'
个字符(数字值为0的字符)。
如果将png文件内容视为字符串('\0' terminated array of characters
)并将其打印为字符串,则在遇到第一个'\0'
字符后它将停止。
所以代码没有问题,fileContents
正确包含png文件(大小为1944字节)
size: 1944 // the png is 1944 bytes
sizeof: 8 // sizeof(fileContents) is the sizeof a pointer (fileContents type is char*) which is 8 bytes
length: 8 // the 9th character in the png file is '\0' (numeric 0)
random: ? // the 56th character in the png file
?PNG // the 5th-8th character is not printable, the 9th character is '\0' so cout stop here
答案 4 :(得分:0)
使用unsigned char与二进制数据一起使用是一个好习惯。 由于支持的字体有限制,随机选择的字符可能无法在控制台窗口中正确显示。您也可以通过以十六进制打印来验证相同的内容,并在十六进制编辑器中打开相同的文件来验证它。请不要忘记删除使用后分配的内存。