从string中取出char的一个问题,忘大家不吝赐教!

刚才从curl中下载到了文件数据,存放在string中

但是目前openssl的AES解密算法,需要放在char*中

不知道今天是不是写得有些晕了,这个测试代码得到的数据,用ofstream保存到本地中,数据不一样。。

char *web_data = new char[original_web_data.length() + 1];
int index = 0;
while (1)
{
memcpy(input_data_tmp, (const void *)(original_web_data.c_str() + index), 16);
fout << input_data_tmp;
if ((index + 16) > original_web_data.length())
{
break;
}
index += 16;
}


上面是部分测试代码,保存下来的图片用十六进制打开是这样的,第一张图为原始图片,第二张为下载后保存的:



这是什么原因造成的?
怎样更快的转到char*中呢。。


明天来继续,贴一个要回去睡觉了。。
...全文
336 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
mujiok2003 2014-02-22
  • 打赏
  • 举报
回复
引用 楼主 zengraoli 的回复:
怎样更快的转到char*中呢。。

char const * p = original_web_data.data();
或者

std::string copy = original_web_data;
char const * p = copy .data();
ofstream要用二进制模式打开。
  • 打赏
  • 举报
回复
引用 3 楼 truelance 的回复:
你一开始就不该用string char数组可以用来表示字符串, 但char数组不仅仅只能用来表示字符串. 你现在要的就是一个二进制字节流(可以用char数组表示), 而不是字符串. 因为字符串中间不允许出现\0, 而字节流允许.
那个是别人的libcurl的一个封装,使用的string。。我一会试试改成使用char的
  • 打赏
  • 举报
回复
引用 2 楼 baichi4141 的回复:
还是不懂为什么初学者都喜欢用字符串保存处理二进制数据 或者楼主只是不知道iostream对于char*的重载视为C风格字符串处理,即处理到第一个'\0'为止 楼主的数据是这么来的:第一次输出8950到1A0A共8个字节,第二次直接遇到0无输出,第三次输出04共1个字节,第四次第五次直接遇到0,第六次输出6FA864共3个字节……
第二个在回去的时候想到了。。 确实有些初学者了,见笑了
  • 打赏
  • 举报
回复
引用 1 楼 Adol1111 的回复:
你确定要用char,而不是用wchar_t?
确定不是wchar_t,我设置使用的是多字节
  • 打赏
  • 举报
回复
引用 12 楼 baichi4141 的回复:
至于为啥超过16字节的就会有一串CDFDFDFDFD跟着,同样是因为C风格字符串到'\0'截止,如果这16个字节内没有'\0',那么按C风格字符串处理的所有函数和重载都会继续处理之后的字节直到遇到'\0'为止 还是那句话,你不认同我的说法没关系,但你必须注意到你的说法无法解释你得到的结果
汗。。我居然把00000000h到00000001h当成了2bytes来看了。。所以= = 这样就可以解释得通了。。 不过按照这么说,“以字节为单位的二进制数据”要怎么进行处理?我只知道从ofstream中可以使用binary,不过对于char*呢?
baichi4141 2014-02-22
  • 打赏
  • 举报
回复

至于为啥超过16字节的就会有一串CDFDFDFDFD跟着,同样是因为C风格字符串到'\0'截止,如果这16个字节内没有'\0',那么按C风格字符串处理的所有函数和重载都会继续处理之后的字节直到遇到'\0'为止
还是那句话,你不认同我的说法没关系,但你必须注意到你的说法无法解释你得到的结果
baichi4141 2014-02-22
  • 打赏
  • 举报
回复
我还是那句话,请分清“字符串”和“以字节为单位的二进制数据” 虽然都用char*操作,但两者完全不同
引用 8 楼 zengraoli 的回复:
但你这里的分析,我并不认同“第一次输出8950到1A0A共8个字节,第二次直接遇到0无输出,第三次输出04共1个字节,第四次第五次直接遇到0,第六次输出6FA864共3个字节……” 第一次的数据完整输出 第二次开始有00没输出 第三次开始也有00还是没输出 第四次,数据为“08 02 00 00 00 6E 92 61”,除非08 02也代表是字符串的终止符,要不然还是会输出08 02的 第五次输出04两个bytes…… 第六次,同第四次的分析一样,42应该也会输出。。 …… 所以中间这个少了08 02和42。。
自己看代码,你每次处理的是16个字节,不是8个 你不认同我的说法无所谓,你发没发现你的想法无法解释你贴出来的结果而我的说法可以解释更加重要
熊熊大叔 2014-02-22
  • 打赏
  • 举报
回复
你一开始就不该用string char数组可以用来表示字符串, 但char数组不仅仅只能用来表示字符串. 你现在要的就是一个二进制字节流(可以用char数组表示), 而不是字符串. 因为字符串中间不允许出现\0, 而字节流允许.
baichi4141 2014-02-22
  • 打赏
  • 举报
回复
还是不懂为什么初学者都喜欢用字符串保存处理二进制数据 或者楼主只是不知道iostream对于char*的重载视为C风格字符串处理,即处理到第一个'\0'为止 楼主的数据是这么来的:第一次输出8950到1A0A共8个字节,第二次直接遇到0无输出,第三次输出04共1个字节,第四次第五次直接遇到0,第六次输出6FA864共3个字节……
  • 打赏
  • 举报
回复
引用 7 楼 mujiok2003 的回复:
[quote=引用 楼主 zengraoli 的回复:] 怎样更快的转到char*中呢。。

char const * p = original_web_data.data();
或者

std::string copy = original_web_data;
char const * p = copy .data();
ofstream要用二进制模式打开。 [/quote] string里面的处理方式应该也是也遇到这种问题的。 ofstream当然已经用ios::binary了,要不然开始的16个bytes就不是这样的了。
  • 打赏
  • 举报
回复
引用 3 楼 truelance 的回复:
你一开始就不该用string char数组可以用来表示字符串, 但char数组不仅仅只能用来表示字符串. 你现在要的就是一个二进制字节流(可以用char数组表示), 而不是字符串. 因为字符串中间不允许出现\0, 而字节流允许.
嗯 是,string的源码无论是length还是c_str()都是到\0终止,iostream也是对于\0而终止 其实简单来说,用string处理带\0比较多的字符串不是一个很好的方式,用char*比较好,比如cout也不好输出\0,这是测试代码,输出根据字节来进行:

// ConsoleApplication2.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include "string"
#include "iostream"
using namespace std;


int _tmain(int argc, _TCHAR* argv[])
{
	char *test = "zeng\0raoli";
	string str = test;
	int str_length = str.length();
	cout << "str : " << str << endl;
	cout << "str_length : " << str_length << endl;

	char *test2 = new char[str_length + 1];
	memset(test2, 0, str_length + 1);
	memcpy(test2, str.c_str(), str.length());
	test2[str_length] = '\0';
	cout << "test2 : " << test2 << endl;

	// 使用string::c_str拷贝到char*
	char test3[16];
	memset(test3, 0, 16);
	memcpy(test3, str.c_str(), 10);
	for (int i = 0; i < 10; i++)
	{
		cout << test3[i];
	}

	// 使用char*拷贝到char*
	char test4[16];
	memset(test4, 0, 16);
	memcpy(test4, test, 10);
	// 直接输出test4
	cout << test4 << endl;
	// 逐个输出test4
	for (int i = 0; i < 10; i++)
	{
		cout << test4[i];
	}
	cout << "\r\n";


	if (test2)
	{
		delete[] test2;
		test2 = NULL;
	}

	return 0;
}
  • 打赏
  • 举报
回复
引用 2 楼 baichi4141 的回复:
还是不懂为什么初学者都喜欢用字符串保存处理二进制数据 或者楼主只是不知道iostream对于char*的重载视为C风格字符串处理,即处理到第一个'\0'为止 楼主的数据是这么来的:第一次输出8950到1A0A共8个字节,第二次直接遇到0无输出,第三次输出04共1个字节,第四次第五次直接遇到0,第六次输出6FA864共3个字节……
原来libcurl的封装用到了string,因为方便,直接追加到后面就行了: web_data->append(data, len); 但我没注意到的是这个web_data到\0处理起来就会出现问题,不容易再转换成char*,然后进去openssl中处理。。 后面把这个string换成了char*,char*的重新分配替换掉了web_data->append,数据也就不需要再转换成char*而是可以直接处理了。这样就没上面的问题了。 都怪没注意到,c++处理char*只到\0终止。。 做点记录,以后统一,要么同时只用string,要么只用char*。。实在不行,才考虑两者中的转换。 ======================================================= 但你这里的分析,我并不认同“第一次输出8950到1A0A共8个字节,第二次直接遇到0无输出,第三次输出04共1个字节,第四次第五次直接遇到0,第六次输出6FA864共3个字节……” 第一次的数据完整输出 第二次开始有00没输出 第三次开始也有00还是没输出 第四次,数据为“08 02 00 00 00 6E 92 61”,除非08 02也代表是字符串的终止符,要不然还是会输出08 02的 第五次输出04两个bytes…… 第六次,同第四次的分析一样,42应该也会输出。。 …… 所以中间这个少了08 02和42。。
Adol1111 2014-02-21
  • 打赏
  • 举报
回复
你确定要用char,而不是用wchar_t?

64,637

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧