免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: kingink1983
打印 上一主题 下一主题

[C] 请教有关字符串输出问题 [复制链接]

论坛徽章:
0
11 [报告]
发表于 2008-11-20 16:10 |只看该作者

回复 #9 yangsf5 的帖子

  1. static char* get_ucs2str(const uint16_t* inbuf, uint16_t inlen)
  2. {
  3.   char* outbuf = calloc(inlen, 2);
  4.   char* q;
  5.   int i;

  6.   if (!outbuf) {
  7.     mp_msg(MSGT_HEADER, MSGL_ERR, MSGTR_MemAllocFailed);
  8.     return NULL;
  9.   }
  10.   q = outbuf;
  11.   for (i = 0; i < inlen / 2; i++) {
  12.     uint8_t tmp;
  13.     PUT_UTF8(AV_RL16(&inbuf[i]), tmp, *q++ = tmp;)
  14.   }
  15.   return outbuf;
  16. }
复制代码


这个是mplayer使用函数,我直接粘贴过来的。

论坛徽章:
1
天蝎座
日期:2013-08-25 10:27:22
12 [报告]
发表于 2008-11-20 16:19 |只看该作者

回复 #11 kingink1983 的帖子

我只是粗略的看了下。

你自己先仔细看看,inbuf参数、PUT_UTF8宏。

看看宏PUT_UTF8在处理inbuf参数后有没有在结尾放个'\0';
或者没有放'\0',那就看看inbuf本身在结尾是否有'\0'。

论坛徽章:
1
天蝎座
日期:2013-08-25 10:27:22
13 [报告]
发表于 2008-11-20 16:23 |只看该作者
printf("Title: %s\n", string);


我的想法是,如果你这个string结尾没有'\0',打印的就很有可能是乱码。。
这个或许比你在楼顶的说法更有说服力。

论坛徽章:
0
14 [报告]
发表于 2008-11-20 16:37 |只看该作者

回复 #12 yangsf5 的帖子

  1. /*!
  2. * \def PUT_UTF8(val, tmp, PUT_BYTE)
  3. * converts a 32-bit unicode character to its UTF-8 encoded form (up to 4 bytes long).
  4. * \param val is an input only argument and should be of type uint32_t. It holds
  5. * a ucs4 encoded unicode character that is to be converted to UTF-8. If
  6. * val is given as a function it's executed only once.
  7. * \param tmp is a temporary variable and should be of type uint8_t. It
  8. * represents an intermediate value during conversion that is to be
  9. * outputted by PUT_BYTE.
  10. * \param PUT_BYTE writes the converted UTF-8 bytes to any proper destination.
  11. * It could be a function or a statement, and uses tmp as the input byte.
  12. * For example, PUT_BYTE could be "*output++ = tmp;" PUT_BYTE will be
  13. * executed up to 4 times for values in the valid UTF-8 range and up to
  14. * 7 times in the general case, depending on the length of the converted
  15. * unicode character.
  16. */
  17. #define PUT_UTF8(val, tmp, PUT_BYTE)\
  18.     {\
  19.         int bytes, shift;\
  20.         uint32_t in = val;\
  21.         if (in < 0x80) {\
  22.             tmp = in;\
  23.             PUT_BYTE\
  24.         } else {\
  25.             bytes = (av_log2(in) + 4) / 5;\
  26.             shift = (bytes - 1) * 6;\
  27.             tmp = (256 - (256 >> bytes)) | (in >> shift);\
  28.             PUT_BYTE\
  29.             while (shift >= 6) {\
  30.                 shift -= 6;\
  31.                 tmp = 0x80 | ((in >> shift) & 0x3f);\
  32.                 PUT_BYTE\
  33.             }\
  34.         }\
  35.     }
复制代码

  1. static inline int av_log2(unsigned int v)
  2. {
  3.     int n;

  4.     n = 0;
  5.     if (v & 0xffff0000) {
  6.         v >>= 16;
  7.         n += 16;
  8.     }
  9.     if (v & 0xff00) {
  10.         v >>= 8;
  11.         n += 8;
  12.     }
  13.     n += ff_log2_tab[v];

  14.     return n;
  15. }
复制代码
  1. const uint8_t ff_log2_tab[256]={
  2.         0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
  3.         5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
  4.         6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
  5.         6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
  6.         7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
  7.         7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
  8.         7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
  9.         7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
  10. };
复制代码


这里就是get_ucs2str()所使用的所有的宏和函数等,没有发现它给结尾加'\0'。原来的字符串也是有'\0'的。

我用编译后的程序连接mms:地址时,就是通过调用asf_read_head() (in readhead.c file)将数据按照结构的要求进行读取,如果title,author等所有的内容都存在的时候,则能和mplayer在控制台中显示的一样,如果有些串的内容不存在,就会出现乱码,或者输出信息类型不全问题。

通过分分析HEX分析文件,对于空和一般的字符用的长度不同

论坛徽章:
0
15 [报告]
发表于 2008-11-20 16:40 |只看该作者

回复 #13 yangsf5 的帖子

因为title指向的结构的一个分量,它所指向的字符串应该不会出现问,最有可能的也就是最后一个rating分量指向的串有这个问题

论坛徽章:
0
16 [报告]
发表于 2008-11-20 16:57 |只看该作者

回复 #15 kingink1983 的帖子

  1. ///////////////////////////
  2. // ASF Content Description
  3. ///////////////////////////
  4. typedef struct  __attribute__((packed)) {
  5.   uint16_t title_size;
  6.   uint16_t author_size;
  7.   uint16_t copyright_size;
  8.   uint16_t comment_size;
  9.   uint16_t rating_size;
  10. } ASF_content_description_t;
复制代码

这个结构中的每个变量所附的值为其所对应的字符串的长度,这里读取的串是pos的位置加上这个结构的大小(10)处开始的。原理不复杂,搞不定,汗……

my.JPG (3.5 KB, 下载次数: 17)

我的程序输出的信息

我的程序输出的信息

2.jpg (9.39 KB, 下载次数: 15)

读到文件中的结构和其指向的数据

读到文件中的结构和其指向的数据

3.jpg (3.03 KB, 下载次数: 16)

mplayer的输出信息

mplayer的输出信息

论坛徽章:
1
天蝎座
日期:2013-08-25 10:27:22
17 [报告]
发表于 2008-11-20 21:07 |只看该作者
根据你的打印,len值跟文件中的那些字符串的长度+1相符么?

论坛徽章:
0
18 [报告]
发表于 2008-11-20 22:15 |只看该作者
原帖由 yangsf5 于 2008-11-20 21:07 发表
根据你的打印,len值跟文件中的那些字符串的长度+1相符么?

是当输出内容为空时,长度就是2,如果有内容输出的话,则字节的长度为输出内容的2倍(含结束符)。再有就是,我的出现乱码,并缺少一项comments

[ 本帖最后由 kingink1983 于 2008-11-20 22:31 编辑 ]

论坛徽章:
1
天蝎座
日期:2013-08-25 10:27:22
19 [报告]
发表于 2008-11-20 22:36 |只看该作者

回复 #18 kingink1983 的帖子

你每次用len来表示相应内容的长度的。
现在主要看你len的打印出来的长度是否跟文件中相应内容的长度一致,如果不一致,就是你前边解析文件的函数没有正确工作。

如果不一致,你就要修改那个解析文件的函数,并且保证解析出来的各内容的的长度为文件中的实际字符串长度加1(这个加1是用来存储'\0'的)。

另外要保证wstring = (uint16_t*)&hdr[pos];得到的wstring是c风格字符串。

论坛徽章:
0
20 [报告]
发表于 2008-11-20 22:40 |只看该作者

发一个有输出内容的

这个输出 title:Traveling Night
author:Joel Hanson and Sara Groves

当然后面还有一项长度为3C长度个字符,和一个长度为2的“空”串吧

jite.jpg (30.98 KB, 下载次数: 17)

jite.jpg
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP