- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
新来的,如果我没有适本地提出问题,请告诉我。
我正在尝试从文件数据动态创建字节序列。这是我遇到问题的代码(我意识到打印是一种糟糕的调试方式,但问题似乎微不足道,而且我在 gdb 中没有看到太多其他内容)。编辑以包含一个编译示例。实际代码要长得多,不想给任何人带来负担。
#include <stdio.h>
#include <stdlib.h>
int main() {
FILE *fpt;
unsigned char *file;
int file_size, i;
// File ops
fpt = fopen("test.txt", "rb");
fseek(fpt, 0L, SEEK_END);
file_size = ftell(fpt);
fseek(fpt, 0L, SEEK_SET);
file = (unsigned char *) calloc(sizeof(unsigned char), file_size);
fread(file, file_size, sizeof(unsigned char), fpt);
fclose(fpt);
int str_len = 1;
unsigned char *string = (unsigned char *)calloc(sizeof(unsigned char), str_len);
unsigned char *next_byte = (unsigned char *)calloc(sizeof(unsigned char),1);
i = 1;
*string = *file;
// Build byte sequence
while (i < file_size) {
*next_byte = *(file + i);
str_len++;
string = realloc(string, str_len);
if (i==1)printf("string+char = %04X\n", (*string << 8) | *next_byte);
*string = (*string << 8) | *next_byte;
if (i==1)printf("string+char = %04X\n", *string);
i++;
}
return 0;
}
// I realize I need to free memory
假设我的 test.txt 仅包含
ABC
用十六进制编辑器查看我会看到
41 42 43 0A
两次打印的输出是:
字符串+字符 = 4142 字符串+字符 = 0042
我的问题是为什么第一个打印给出了我想要的结果,而第二个打印却没有?我意识到 unsigned char 是一个字节,因此向左移动 8 位应该得到零。我不明白为什么直接打印位运算会得到我想要的结果。
是否有更好的方法将单个字节连接到字节序列?
最佳答案
这对我来说有点困惑。
我无法看出代码示例的行为与您预期的不同。
让我举例说明...
我在示例代码中添加了一些打印,请参阅下面的 concat.c 了解完整的程序,但让我们重点关注 while 循环的移位。仅供引用,到目前为止的所有内容(从“test.txt”等加载 4 个字节)似乎都按预期工作。
具体代码片段如下:
if (i==1)printf("string+char = %04X\n", (*string << 8) | *next_byte);
*string = (*string << 8) | *next_byte;
if (i==1)printf("string+char = %04X\n", *string);
我认为带有 %04x 的 printf() 表明 *string 中的内容比实际存在的内容更多。
我修改了移位表达式,以使用一系列单独的变量来分解我认为它正在执行的操作,以便我可以查看每个变量的值。
/* original: *string = (*string << 8) | *next_byte; */
printf(" explicit shifting...\n");
unsigned char a = *string;
printf(" Lets print 'a' as %%x and %%04x just to verify zero padding doesn't change anything.\n");
printf(" a=%x a=%04x sizeof(a)=%ld\n", a, a, sizeof(a) );
unsigned char b = a << 8;
printf(" b=%x : b = a << 8 yielded all zero bits.\n", b);
unsigned char c = *next_byte;
printf(" c=%x : c = *next_byte as expected.\n", c);
unsigned char d = b | c;
printf(" d=%x : d bitwise-or of 0 w/c yields, well, c.\n", d);
// pick up with original...
// note that we're always overwriting string[0].
// the following is the same as saying:
// string[0] = d; // assuming 'd' is assigned as above.
*string = (*string << 8) | *next_byte;
// If you want to use shift and accumulate 4 bytes
// you probably want *string to be a long.
printf(" after shift: string[0]=%x, next_byte[0]=%x\n", string[0], next_byte[0] );
if (i==1) printf("string+char = %04X\n", *string);
以下是第一次执行 while 循环。
i = 1,next_byte = 0x42。
(完整输出见下文)
explicit shifting...
Lets print 'a' as %x and %04x just to verify zero padding doesn't change anything.
a=41 a=0041 sizeof(a)=1
b=0 : b = a << 8 yielded all zero bits.
c=42 : c = *next_byte as expected.
d=42 : d bitwise-or of 0 & c yields, well, c.
after shift: string[0]=42, next_byte[0]=42
string+char = 0042
原始程序的最后一行显示 string+char = 0042 但这不是因为 printf 格式显示 printf("string+char = %04X\n",*字符串);?我的意思是... *string 的底层值只是 0x42,这就是它应该做的,是吗?
话虽如此,我认为这与“移位”无关,因为它不断地覆盖字符串的第一个字节,例如字符串[0]。
这是另一个输出片段,这是我在 while 循环之后添加的一些打印内容(再次参见下面的 concat.c)以获取完整代码。
After while loop. just for fun, let's print out string...
string[0]=0a (string+0)=0x114d010
string[1]=00 (string+1)=0x114d011
string[2]=00 (string+2)=0x114d012
string[3]=00 (string+3)=0x114d013
done.
$
在这里你可以看到string的值非常空。
字符串实际上保留了最后一个字符,0x0a。
由于我不清楚的原因,字符串是用第一个字符“A”初始化的,在 while 循环开始之前。好歹...
在while循环期间,string已被重新分配多次。 (例如 string = realloc(string, str_len); - 为什么这样做,顺便说一句?)
那么...您是否想要通过移位和按位或将字符“ABC\n”级联到字符串?
如果你有类似 long my4bytes; 而不是 string 我可以看到移位和按位 - 或者在收集各个字节时“有帮助”。
但是...字符串本质上是一个字节数组(好吧,无符号字符数组)。
假设您想将 string 保留为字节数组,我认为您最好这样做:string[i] = *next_byte;
所以。您可以通过多种方式来编写它; while 循环有点困惑,所以我把它留给你。 (这是可以理解的......我可以想象困惑是因为您将原始示例削减到足够小以发布在原始问题中)。
无论如何,这是否有助于为您指明有用的方向?
或者...我是否错过了最初问题的意图?
$ cat test.txt
ABC
$ hexdump -C test.txt
00000000 41 42 43 0a |ABC.|
00000004
$ gcc concat.c
$ ./a.out
file_size=4
file[0]=41 (file+0)=0x114d240
file[1]=42 (file+1)=0x114d241
file[2]=43 (file+2)=0x114d242
file[3]=0a (file+3)=0x114d243
--- Build byte sequence
while: i=1
file[i]=42 file=0x114d240
next_byte[0]=42 next_byte=0x114d030
string+char = 4142
before shift: string[0]=0041, next_byte[0]=0042
explicit shifting...
Lets print 'a' as %x and %04x just to verify zero padding doesn't change anything.
a=41 a=0041 sizeof(a)=1
b=0 : b = a << 8 yielded all zero bits.
c=42 : c = *next_byte as expected.
d=42 : d bitwise-or of 0 w/c yields, well, c.
after shift: string[0]=42, next_byte[0]=42
string+char = 0042
while: i=2
file[i]=43 file=0x114d240
next_byte[0]=43 next_byte=0x114d030
before shift: string[0]=0042, next_byte[0]=0043
explicit shifting...
Lets print 'a' as %x and %04x just to verify zero padding doesn't change anything.
a=42 a=0042 sizeof(a)=1
b=0 : b = a << 8 yielded all zero bits.
c=43 : c = *next_byte as expected.
d=43 : d bitwise-or of 0 w/c yields, well, c.
after shift: string[0]=43, next_byte[0]=43
while: i=3
file[i]=0a file=0x114d240
next_byte[0]=0a next_byte=0x114d030
before shift: string[0]=0043, next_byte[0]=000a
explicit shifting...
Lets print 'a' as %x and %04x just to verify zero padding doesn't change anything.
a=43 a=0043 sizeof(a)=1
b=0 : b = a << 8 yielded all zero bits.
c=a : c = *next_byte as expected.
d=a : d bitwise-or of 0 w/c yields, well, c.
after shift: string[0]=a, next_byte[0]=a
After while loop. just for fun, let's print out string...
string[0]=0a (string+0)=0x114d010
string[1]=00 (string+1)=0x114d011
string[2]=00 (string+2)=0x114d012
string[3]=00 (string+3)=0x114d013
done.
$
#include <stdio.h>
#include <stdlib.h>
int main() {
FILE *fpt;
unsigned char *file;
int file_size, i;
// File ops
fpt = fopen("test.txt", "rb");
fseek(fpt, 0L, SEEK_END);
file_size = ftell(fpt);
printf("file_size=%d\n", file_size);
fseek(fpt, 0L, SEEK_SET);
//file = (unsigned char *) calloc(sizeof(unsigned char), file_size);
file = calloc( file_size, file_size);
fread(file, file_size, sizeof(unsigned char), fpt);
fclose(fpt);
int str_len = 1;
unsigned char *string =
(unsigned char *)calloc(sizeof(unsigned char), str_len);
unsigned char *next_byte =
(unsigned char *)calloc(sizeof(unsigned char),1);
i = 1;
//printf(" file[0]=%02x file=%p\n", file[0], file );
//printf("before: string[0]=%02x string=%p\n", string[0], string );
*string = *file;
//printf("after: string[0]=%02x string=%p\n", string[0], string );
for( int idx = 0; idx < file_size; ++idx ) {
printf(" file[%d]=%02x (file+%d)=%p\n", idx, file[idx], idx, (file+idx) );
}
printf("\n--- Build byte sequence\n");
while (i < file_size) {
printf("while: i=%d\n", i );
printf(" file[i]=%02x file=%p\n", file[i], file );
*next_byte = *(file + i);
printf(" next_byte[0]=%02x next_byte=%p\n", next_byte[0], next_byte );
str_len++;
string = realloc(string, str_len);
if (i==1) printf("string+char = %04X\n", (*string << 8) | *next_byte);
printf(" before shift: string[0]=%04x, next_byte[0]=%04x\n", string[0], next_byte[0] );
/* original: *string = (*string << 8) | *next_byte; */
printf(" explicit shifting...\n");
unsigned char a = *string;
printf(" Lets print 'a' as %%x and %%04x just to verify zero padding doesn't change anything.\n");
printf(" a=%x a=%04x sizeof(a)=%ld\n", a, a, sizeof(a) );
unsigned char b = a << 8;
printf(" b=%x : b = a << 8 yielded all zero bits.\n", b);
unsigned char c = *next_byte;
printf(" c=%x : c = *next_byte as expected.\n", c);
unsigned char d = b | c;
printf(" d=%x : d bitwise-or of 0 w/c yields, well, c.\n", d);
// pick up with original...
// note that we're always overwiting string[0].
// the following is the same as saying:
// string[0] = d; // ssuming 'd' is assigned as above.
*string = (*string << 8) | *next_byte;
// If you want to use shift and accumulate 4 bytes
// you probably want *string to be a long.
printf(" after shift: string[0]=%x, next_byte[0]=%x\n", string[0], next_byte[0] );
if (i==1) printf("string+char = %04X\n", *string);
i++;
}
printf("\nAfter while loop. just for fun, let's print out string...\n");
for(int idx = 0; idx < str_len; ++idx ) {
printf(" string[%d]=%02x (string+%d)=%p\n", idx, string[idx], idx, (string+idx) );
}
printf("done.\n");
return 0;
}
// I realize I need to free memory
附:打印实际上是解决问题的好方法;不要犹豫,继续添加它们,直到您的代码所做的事情变得显而易见。
关于将单个字节连接到字节序列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35354728/
我正在阅读 Python 文档以真正深入了解 Python 语言,并遇到了 filter 和 map 函数。我以前使用过过滤器,但从未使用过映射,尽管我在 SO 上的各种 Python 问题中都见过这
当我尝试打印 BST 的级别顺序时,这个问题提示了我。 这是一个 Pre-Order Sequence: 4, 1, 2, 3, 5, 6, 7, 8 In_order Sequence : 1, 2
我的代码在 main(序列测试;)的第一行出现错误,指出它是对 sequence::sequence() 的 undefined reference 。我无法更改 main 中的代码。有谁知道我该如何
这可能很简单,但我在通常的 latex 指南中找不到任何相关内容。在这句话中: {\em hello\/} “\/”的目的是什么? 最佳答案 这就是所谓的斜体校正。其目的是确保斜体文本后有适当的间距。
当我从 Postgresql 表中删除所有记录,然后尝试重置序列以在插入时开始一个编号为 1 的新记录时,我得到不同的结果: SELECT setval('tblname_id_seq', (SELE
在版本10.0.3中,MariaDB引入了一种称为序列的存储引擎。 其ad hoc为操作生成整数序列,然后终止。 该序列包含正整数,以降序或升序排列,并使用起始,结束和递增值。 它不允许在多个查询中
如何在 Groovy 中获取给定数字的序列,例如: def number = 169 // need a method in groovy to find the consecutive number
基本上,如果这是 .NET,它看起来像这样: ISomething { string A { get; } int B { get; } } var somethings = new List
说以下代码部分(同一块): A <= 1 A <= 2 变量 A 总是被赋值为 2 吗?还是会出现竞争条件并分配 1 或 2? 我对非阻塞赋值的理解是,由硬件在 future 分配变量 A,因此它可能
在运行 WiX 设置时,我正在寻找操作列表及其顺序。不知何故,官方网站似乎没有提供任何信息。 基本问题是我想正确安排我的自定义操作。通常我需要使用 regsvr32.exe 注册一个 DLL,而这只能
F#初学者在这里 我想创建一个类型,它是具有至少一个元素的另一种具体类型(事件)的序列。任何其他元素都可以在以后随时添加。通常在 C# 中,我会创建一个具有私有(private) List 和公共(p
作为构建过程和不断发展的数据库的一部分,我试图创建一个脚本,该脚本将删除用户的所有表和序列。我不想重新创建用户,因为这将需要比所允许的更多的权限。 我的脚本创建了一个过程来删除表/序列,执行该过程,然
我想恢复两个向量的第一个日期和相同向量的第二个日期之间的日期序列,.... 这是一个例子: dates1 = as.Date(c('2015-10-01', '2015-03-27', '2015-0
这个问题已经有答案了: sql ORDER BY multiple values in specific order? (12 个回答) 已关闭 9 年前。 我有一个 sql 语句,我想要ORDER
我想恢复两个向量的第一个日期和相同向量的第二个日期之间的日期序列,.... 这是一个例子: dates1 = as.Date(c('2015-10-01', '2015-03-27', '2015-0
在用java编写代码时,我需要用“],[”分割字符串。下面是我的代码。 try (BufferedReader reader = new BufferedReader(new InputStreamR
这个问题已经有答案了: Project Euler Question 14 (Collatz Problem) (8 个回答) 已关闭 9 年前。 我正在尝试查找数字的 Collatz 序列。以下
我有一个例程函数process_letter_location(const char& c, string &word)。 在我的 main 中,我声明了一系列字符串变量,如下所示: string s
我需要找到最长的多米诺骨牌链,给定一组 12 个随机挑选的多米诺骨牌。我已经递归地生成了多米诺骨牌的所有可能性(使用 0 到 12 的面值有 91 种可能性)。多米诺骨牌由一 block “砖 blo
我有这个数据结构 Seq,它继承了类 vector 但有一些额外的功能。使用这个数据结构 Seq 我有这个预定义的数据结构: typedef Seq > MxInt2d; 我现在想要一个包含多个 Mx
我是一名优秀的程序员,十分优秀!