忘记密码   免费注册 查看新帖 |

ChinaUnix.net

  平台 论坛 博客 文库 频道自动化运维 虚拟化 储存备份 C/C++ PHP MySQL 嵌入式 Linux系统
最近访问板块 发新帖
查看: 1600 | 回复: 2

[C] 对字符串进行位运算,用C语言,结果不对 [复制链接]

论坛徽章:
0
发表于 2018-08-08 18:56 |显示全部楼层
一个长度为12个字节的字符串"abcdefghijkl",把这段8*12bit长度的数据的偶数位(二进制位)变成0,即进行位运算。因为逐个字节运算速度慢,我想每次运算4个字节(即32bit)。使用循环,每次运算4个字节,当然是循环3次。我的办法是,把每4个字节看作一个long整型数据,位运算之后,使用memcpy()函数把结果拷贝到目标指针上。这样循环3次。下面写的代码,得不到正确的结果。

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4. /**
  5. * 打印数值二进制值的函数
  6. **/
  7. void printNumber(unsigned long n, int length)
  8. {
  9.     char str[length];
  10.     itoa(n,str,2);//2即是代表转换为2进制
  11.     //补足前面的0
  12.     int count = length - strlen(str);
  13.     int i;
  14.     for(i=0; i<count; ++i)
  15.     {
  16.         printf("0");
  17.     }
  18.     //
  19.     printf("%s",str);
  20. }

  21. /**
  22. * 打印字符串二进制值的函数
  23. **/
  24. void printString(char *s)
  25. {
  26.     char c;
  27.     unsigned long j=(unsigned long)s + strlen(s);
  28.     for(; (unsigned long)s<j; s++)
  29.     {
  30.         c = *s;
  31.         printNumber((unsigned long)c, 8);
  32.     }
  33. }

  34. /**
  35. * 主函数
  36. */
  37. int main(int argc, char *argv[])
  38. {
  39.         unsigned int length= 8;
  40.     char src[8] = "abcdefgh";
  41.     char dest[8] = "tttttttt";        //存放结果
  42.     unsigned long* srcLong = src;
  43.     unsigned long* destLong = dest;
  44.     //
  45.     unsigned long key1 = 0xaaaaaaaa;                //1010....
  46.     unsigned long n;
  47.     //
  48.     printNumber(key1, 32);printNumber(key1, 32); puts(":key1");
  49.     printString(src); puts(":src");
  50.     //
  51.     //unsigned long * endLong = src + 8;
  52.         unsigned int count = length/4;
  53.         unsigned int i;
  54.     for(i=0; i<count; i++) //srcLong < endLong
  55.     {
  56.         n = (*srcLong) & key1;
  57.         //printString((char*)&n);
  58.         memcpy((void *)destLong, (void *)&n, 4);
  59.         srcLong += 4;
  60.                 destLong +=4;
  61.     }
  62.         printString(dest); puts(":dest");


  63.     return 0;
  64. }
复制代码


论坛徽章:
14
巨蟹座
日期:2013-11-19 14:09:4615-16赛季CBA联赛之青岛
日期:2016-07-05 12:36:0515-16赛季CBA联赛之广东
日期:2016-06-29 11:45:542015亚冠之全北现代
日期:2015-07-22 08:09:472015年辞旧岁徽章
日期:2015-03-03 16:54:15巨蟹座
日期:2014-12-29 08:22:29射手座
日期:2014-12-05 08:20:39狮子座
日期:2014-11-05 12:33:52寅虎
日期:2014-08-13 09:01:31巳蛇
日期:2014-06-16 16:29:52技术图书徽章
日期:2014-04-15 08:44:01天蝎座
日期:2014-03-11 13:06:45
发表于 2018-08-09 08:59 |显示全部楼层
看不懂,也猜不出你想干什么
char src[8] = "abcdefgh"; 这些你是怎么编译通过的?
srcLong += 4; 等等应该是 srcLong += 1; 吧?

论坛徽章:
14
巨蟹座
日期:2013-11-19 14:09:4615-16赛季CBA联赛之青岛
日期:2016-07-05 12:36:0515-16赛季CBA联赛之广东
日期:2016-06-29 11:45:542015亚冠之全北现代
日期:2015-07-22 08:09:472015年辞旧岁徽章
日期:2015-03-03 16:54:15巨蟹座
日期:2014-12-29 08:22:29射手座
日期:2014-12-05 08:20:39狮子座
日期:2014-11-05 12:33:52寅虎
日期:2014-08-13 09:01:31巳蛇
日期:2014-06-16 16:29:52技术图书徽章
日期:2014-04-15 08:44:01天蝎座
日期:2014-03-11 13:06:45
发表于 2018-08-09 09:40 |显示全部楼层
瞎猜猜
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <limits.h>
  4. #include <assert.h>

  5. void print_binary( unsigned long val, size_t len )
  6. {
  7.     assert( len <= sizeof(val)*CHAR_BIT ); // 断言 len 不大于 unsigned long 拥有的位数

  8.     for( size_t i=0; i!=len; ++i )
  9.         putchar( '0'+(((1ul<<(len-1-i))&val)!=0) );
  10. }

  11. void print_binary_s( const char* s )
  12. {
  13.     for( ; *s; ++s )
  14.         print_binary( *s, CHAR_BIT );
  15. }

  16. int main( void )
  17. {
  18.     const char* src = "abcdefgh";
  19.     unsigned long key = 0xAAAAAAAA;
  20.     char dst[9];

  21.     const size_t src_len = strlen(src);
  22.     assert( sizeof(dst) > src_len ); // 断言 dst 能存得下结果
  23.     assert( src_len%sizeof(unsigned long) == 0 ); // 断言你的 src 拥有整数个 unsigned long,否则头尾要特殊对待
  24.     assert( ((uintptr_t)src)%sizeof(unsigned long) == 0 ); // 断言你的 src 地址 unsigned long 对齐,否则在某些CPU上会出问题
  25.     for( size_t i=0; i!=src_len/sizeof(unsigned long); ++i )
  26.         ((unsigned long*)dst)[i] = ((unsigned long*)src)[i] & key;
  27.     dst[src_len] = '\0';

  28.     putchar( ' ' );
  29.     putchar( ' ' );
  30.     print_binary_s( src );
  31.     putchar('\n');

  32.     putchar( '&' );
  33.     putchar( ' ' );
  34.     print_binary( key, sizeof(key)*CHAR_BIT );
  35.     print_binary( key, sizeof(key)*CHAR_BIT );
  36.     putchar('\n');

  37.     putchar( '=' );
  38.     putchar( ' ' );
  39.     print_binary_s( dst );
  40.     putchar('\n');
  41. }
复制代码


输出
  0110000101100010011000110110010001100101011001100110011101101000
& 1010101010101010101010101010101010101010101010101010101010101010
= 0010000000100010001000100010000000100000001000100010001000101000

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

本版积分规则

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号 北京市公安局海淀分局网监中心备案编号:11010802020122
广播电视节目制作经营许可证(京) 字第1234号 中国互联网协会会员  联系我们:wangnan@it168.com
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP