求助 UNICODE 写文件出现好多 烫烫烫

woshilaidajiangyoudi 2011-07-07 04:58:12
int __cdecl CExceptionReport::_tprintf(const TCHAR * format, ...)
{
TCHAR szBuff[1024];
int retValue;
DWORD cbWritten;
va_list argptr;

va_start( argptr, format );
retValue = vswprintf( szBuff, format, argptr );
va_end( argptr );

WriteFile(m_hReportFile, szBuff, retValue * sizeof(TCHAR), &cbWritten, 0 );

return retValue;
}

输出了20多MB 除了部分数据正确 输出的全是烫烫烫 还有中文显示不出来
...全文
484 29 打赏 收藏 转发到动态 举报
写回复
用AI写文章
29 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
感谢回答 . BOM头已经早就加上了 没用 最后 直接把这个类改成ANSI 的了 直接搞定。。。 调试半天没找到错误 我晕。 反正正常了 散分
W1nds 2011-07-08
  • 打赏
  • 举报
回复
如果你写入的文件的格式是ANSI的话
就会出现乱码
exceed_me 2011-07-08
  • 打赏
  • 举报
回复
编码问题很头大!
辰岡墨竹 2011-07-07
  • 打赏
  • 举报
回复
我想错了一点,并不需要_tsetlocale( LC_ALL, _T("");
否则你Write进文件的就是本地编码GBK(代码页936)了。wprintf类函数其参数是wchar_t,但是输出是受locale影响的。不指定locale,输出的才是Unicode;如果指定了locale,会转换为locale。
之所以你中文不能正确显示,是因为你的文件没有加BOM。所以编辑器当作ANSI编码打开文件了。
应该再加一个#ifdef _UNICODE,判断如果是UNICODE的话,先用WriteFile写一个0xFEFF进去,这个是UTF-16LE的BOM。
辰岡墨竹 2011-07-07
  • 打赏
  • 举报
回复

void test( const TCHAR * format, ... )
{
va_list args;
int len;
TCHAR * buffer;

_tsetlocale( LC_ALL, _T(""); // 按当前 Windows 区域设置 locale

va_start( args, format );
len = _vsctprintf( format, args ) + 1 // _vscprintf 不计算末尾 '\0'
buffer = malloc( len * sizeof( TCHAR ) );
_vstprintf( buffer, format, args );

......

free( buffer );
}
辰岡墨竹 2011-07-07
  • 打赏
  • 举报
回复
你还是看看VS.NET 2003里的例子吧:
void test( char * format, ... )
{
va_list args;
int len;
char * buffer;

va_start( args, format );
len = _vscprintf( format, args ) // _vscprintf doesn't count
+ 1; // terminating '\0'
buffer = malloc( len * sizeof( char ) );
vsprintf( buffer, format, args );
printf( buffer );
free( buffer );
}
用malloc而不是固定数组,这样可以避免数组大小不够导致返回负值的问题。
既然你写的是_tprintf,那么建议你用_vstprintf,并用TCHAR替换char,这样可以同时兼容ANSI和Unicode
白云飘飘飘 2011-07-07
  • 打赏
  • 举报
回复
你的用法不对,假定可变参数的第一个参数是字符串,
va_start( argptr, format );
TCHAR * str=va_arg(arpptr,TCHAR *);
直接把str写入文件即可
辰岡墨竹 2011-07-07
  • 打赏
  • 举报
回复
你可以加一个ASSERT断言,判断一下vswprintf返回值是不是大于1024或者是负值。
辰岡墨竹 2011-07-07
  • 打赏
  • 举报
回复
vswprintf_s也是VS2005之后提供的安全字符串函数,你VC6肯定没有。不过现在开发最好还是用比较新的IDE比较好。
辰岡墨竹 2011-07-07
  • 打赏
  • 举报
回复
额,vswprinf从VS2005开始,遵照ISO规范,增加了第二个参数,你用VC6,就只有三个参数。
vswprinf如果返回负值,说明你输出错误,估计你那个vswprintf正好返回了一个负数,然后这个负数被WriteFile当作无符号数解释了,所以就变得特别大。
alweeq86 2011-07-07
  • 打赏
  • 举报
回复
烫烫烫 你就想想是不是字符串下标越界了 我遇到每次都是这样
  • 打赏
  • 举报
回复
报告楼上没有找到这个函数
Ace丶双鱼 2011-07-07
  • 打赏
  • 举报
回复
vswprintf 改成 vswprintf_s
  • 打赏
  • 举报
回复
vc6.。。。。
辰岡墨竹 2011-07-07
  • 打赏
  • 举报
回复
http://msdn.microsoft.com/en-us/library/28d5ce15(v=vs.80).aspx
你用的是VS吧,都WriteFile了,那就得按微软的库来。你查的是别的编译器的吧。
  • 打赏
  • 举报
回复
_CRTIMP int __cdecl vswprintf(wchar_t *, const wchar_t *, va_list);

好像就三个参数把?
辰岡墨竹 2011-07-07
  • 打赏
  • 举报
回复
你自己根本没指定大小,少写一个参数,结果vswprintf把format的指针值当作大小了。
辰岡墨竹 2011-07-07
  • 打赏
  • 举报
回复
int vswprintf(
wchar_t *buffer,
size_t count,
const wchar_t *format,
va_list argptr
);
同学,你的count哪去了?
赵4老师 2011-07-07
  • 打赏
  • 举报
回复
仅供参考

char logstr[1024];
#define ARRSIZE(x) (sizeof(x)/sizeof(x[0]))
void LogV(const char *pszFmt,va_list argp) {
//...
if (-1==vsnprintf(logstr,ARRSIZE(logstr),pszFmt,argp)) logstr[ARRSIZE(logstr)-1]=0;
//...
}
void Log(const char *pszFmt,...) {
va_list argp;

va_start(argp,pszFmt);
LogV(pszFmt,argp);
va_end(argp);
}

  • 打赏
  • 举报
回复
报告楼上 还是那样
加载更多回复(9)

64,682

社区成员

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

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