我正在尝试将证书和png文件加载到C ++中的char *中:
char certPath[] = "./user.pem";
char dataPath[] = "./test.png";
char *certificate = loadFile(certPath);
char *datafile = loadFile(dataPath);
这是我的loadFile()方法:
char* loadFile(char* filename) {
cout << endl << "Loading file: " << filename << endl;
char *contents;
ifstream file(filename, ios::in|ios::binary|ios::ate);
if (file.is_open())
{
int size = file.tellg();
contents = new char [size];
file.seekg (0, ios::beg);
file.read (contents, size);
file.clear();
file.close();
}
printf("contents: %s\n", contents);
cout << endl << "finished loading " << filename << endl;
return contents;
}
这是它产生的输出:
Loading file: ./user.pem
contents: -----BEGIN CERTIFICATE-----
MIID+TCCAuGgAwIBAgIJAJhxZybSGGMgMA0GCSqGSIb3DQEBBQUAMIGSMQswCQYD
VQQGEwJBVDEPMA0GA1UECAwGU3R5cmlhMQ0wCwYDVQQHDARHcmF6MQowCAYDVQQK
DAEvMQowCAYDVQQLDAEvMR0wGwYDVQQDDBRDaHJpc3RvZiBTdHJvbWJlcmdlcjEs
MCoGCSqGSIb3DQEJARYdc3Ryb21iZXJnZXJAc3R1ZGVudC50dWdyYXouYXQwHhcN
MTIwMjE0MjEwMzA4WhcNMTMwMjEzMjEwMzA4WjCBkjELMAkGA1UEBhMCQVQxDzAN
BgNVBAgMBlN0eXJpYTENMAsGA1UEBwwER3JhejEKMAgGA1UECgwBLzEKMAgGA1UE
CwwBLzEdMBsGA1UEAwwUQ2hyaXN0b2YgU3Ryb21iZXJnZXIxLDAqBgkqhkiG9w0B
CQEWHXN0cm9tYmVyZ2VyQHN0dWRlbnQudHVncmF6LmF0MIIBIjANBgkqhkiG9w0B
AQEFAAOCAQ8AMIIBCgKCAQEA15ISaiXMSTVnmGtEF+bbhmVQk+4voU1pUZlOMVBj
QKjfPgCtgrmRaY8L+d6Pu61urFE1QrsfNJdDJRYs87Cc1eZgkvOXz0fSE2DHVNE2
i9YdFR8ea5niU5ATFZwiDIEhfCAcXWcEHWtZBB4yYYISsBkFxq6UBniGV+p7XOtE
aAtriBP0PZ4KUo+arJLStbwt4f9tBeytKowaKVNGlOpBgj7TG4bw8yA7Avdx8s+k
sReSxYteo0o9clIqISdKL0pRdzXP0Zrix54mBIfsxojfCW2SvqvLLLxtJlRKriQj
JfBc4koS6yAoktx7CvzcepGQk65ZGl0TNlteG4FJqy5yBQIDAQABo1AwTjAdBgNV
HQ4EFgQU1/g63xTix2Vs0zv2d3wVX9FGvVQwHwYDVR0jBBgwFoAU1/g63xTix2Vs
0zv2d3wVX9FGvVQwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAHyvI
0L+ibesg45qUxx2OQb37HA9aRpR3wYpt6d5Rd1x2pfqumrKeV/42XWodZJSkU3sH
EX8V2xKwNoUBsPb/q54S9suCHwE33XtWjLvJyR9v2wd2HjNRYdGF9XoYdpsOpcAk
/kaZ2pExzLAPDg5pTsqY9dpCFWnyccZUO1CLEeljinOZ4raIj7d6EryWsn+u5pbs
WB12EFaoNCybQ6j5+TIcRs5xdGpVD6qMkm7HUnBn6mtz8Q7qVj9sqo5us4UBRWY8
ie9X494oW59nRuLiZ8dOPGuOXsuCILY44/3eyDh6yvW7G+wrp3eZ7L7eLRSI3+lm
mxqSJNq8Yi6ArfcB+Q==
-----END CERTIFICATE-----
finished loading ./user.pem
Loading file: ./test.png
首先应显示证书的内容,然后显示图像的内容。证书有效,但当我尝试加载图像时,它真的很奇怪。什么都没有了。即使是简单的cout或printf也没有显示在控制台上,但程序不会崩溃......
有什么建议吗?
答案 0 :(得分:2)
您的错误是您在PNG标头的开头有\ 0.
编辑:
变化:
printf("contents: %s\n", contents);
要:
std::cout.write( contents, size );
std::cout.flush();
当然,你必须将尺寸移动到正确的范围内。
答案 1 :(得分:2)
有不同种类的PNG文件。因此可能是PNG图像具有不可打印的字符。如果是这样,则不会使用任何打印功能打印,无论是printf
还是std::cout<<
。
但是,您可以打印不可打印字符的十六进制值:
//write it inside the if-block
for(int i = 0 ; i < size; ++i)
std::cout << std::hex << (int) contents[i];
它将打印每个字符的十六进制值。
您可以使用isprint()
函数测试给定字符是否可打印。
答案 2 :(得分:1)
您无法将png文件的内容打印到控制台,它是一个二进制文件 - 与证书文件不同,后者包含MIME编码的证书,因此是一个常规文本文件。
可打印文件(即文本)仅包含表示标准ASCII字符(0x20 - 0x7F)的字节,并以可预测的方式使用ASCII格式字符(CR,LF等)。此外,它不包含0x00字节,在C / C ++中用于标记字符串的结尾。二进制文件可以包含任何顺序的任何字节。
因此,当您尝试打印它时会发生两件事:a)它会在找到的第一个0x00字节处停止; b)包含非ASCII字符的每个字节将作为特殊字符打印(如果它在控制台的活动代码页中),或者根本没有,并且包含ASCII格式字符的字节将被“执行”,就好像它们一样是文本文件中的实际格式。
结果:要么你根本不会看到任何东西,要么只是将几个奇怪的字符与随机换行符,标签&amp;等
要拥有您所期望的,首先要确切地定义它是什么。你想看到MIME编码的png内容吗?然后你应该使用MIME编码例程(如this)。或者您想打印每个字节的十六进制值?然后,您需要为循环中的每个字节执行std::cout << std::hex << byte
(如Nawaz建议的那样)或printf("%02x")
。
同样对于证书文件,您应该打开文本文件,而不是二进制文件。否则,你会有两个不受欢迎的影响:没有LF规范化(例如,在Windows中,EOL标记为CR + LF,而在Unix / Linux中它只是LF)并且没有处理EOF字符。