引用 | 编辑
csr
2011-05-29 21:47 |
楼主
▼ |
||
x0
/* 程式名称 : ch13_22.c *//* 随机读取某档案的 16 位元资料 */ #include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <ctype.h> #include <math.h> int main(int argc, char *argv[]) { long pos; int fd; int sector; int totalread,totaldigit,totalchar; int i,j; char buffer;请教大大,这64是否代表64位元吗? fd = open(argv,O_RDONLY | O_BINARY); while ( 1 ) { printf("输入磁区 ");这里的磁区,怎会是档案的第一行,而不是磁碟的第x磁区呢? scanf("%d",§or); if ( sector < 0 ) { printf("结束随机读取资料 \n"); break; } pos = (long) sector * 64;请教这里64 .. 访客只能看到部份内容,免费 加入会员 x0
|
引用 | 编辑
ebolaman
2011-06-02 21:28 |
1楼
▲ ▼ |
应该是这样,如果有错误还请大家指教 我最近才刚学 C 而已,不是很熟... buffer 一次读 64 个位元组,就是以上的图中,四个 16 bytes 的横框框的范围 然后以 char 一位元组为单位读取 buffer[i*16+j] ,i 是小蓝框框的左边起始点 位移量,而 j 是在 小蓝框框 内的位移量 我又画了一张 我看了许久,他好像是要模拟 UltraEdit 那样,左边显示 16 个 %3x 的 16 位元码,然后右边显示 16 个 %c 的字元,接着换行 读取是一次读 64 个位元组 但是显示的时候一行只显示 16 个位元组,你也可以把它改成 32 个位元组 所以是把一次的读取量 切成 4 块来显示 还有,buffer[64] 是 64 位元组,而非位元,C 里面像是 sizeof() 得到的都是 "位元组",就是 8 个位元组成的 1 byte = 8 bits x3 |
引用 | 编辑
ebolaman
2011-06-03 18:46 |
3楼
▲ ▼ |
||||||||||
下面是引用 csr 于 2011-06-03 10:44 发表的 : 实作的话会更清楚,我们就拿我从 DesktopNexus 下载的桌布来当作 argv[1] 的字串目标 请将 图片 Chromatic_link_by_k3_studio.jpg (附在此文章最下面) 放置到工作目录下 另外请下载一套免费的 文字/十六进位 编辑软体 (建议下载 Portable 的):RJ TextEd 点选底下的 Editor 并将这张桌布 直接拖曳进去,就可以检视 十六进位码 这是我 修改后的原始码,用这个比较贴近 软体显示的方法: 复制程式 #include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <ctype.h> #include <math.h> int main(int argc, char *argv[]) { long pos; int fd; int sector; int totalread,totaldigit,totalchar; int i,j; char buffer[64]; argv[1]="Chromatic_link_by_k3_studio.jpg"; fd = open(argv[1],O_RDONLY | O_BINARY); while ( 1 ) { printf("输入磁区 : "); scanf("%d",& sector); printf("\n"); if ( sector < 0 ) { printf("结束随机读取资料 \n"); break; } pos = (long) sector * 64; if ( lseek(fd,pos,SEEK_SET) == -1 ) { printf("随机读取资料错误 \n"); break; } /* 读取 64 位元组资料如果读不到这么多表示已读到档案末端 */ if ( ( totalread = read(fd,buffer,64) ) != 64 ) printf("EOF : end of file.... \n"); totalchar = totaldigit = totalread; for ( i = 0; i < ceil((float)totalread / 16); i++ ) { for ( j = 0; j < 16; j++ ) { totaldigit--; if ( totaldigit < 0 ) /* 无资料则列空白 */ printf(" "); else /* 否则输出 16 进位值 */ printf("%02X",buffer[i*16+j]<0 ? 255-(~buffer[i*16+j]) : buffer[i*16+j]); if (j&1==1) printf(" "); } printf(" "); /* 16 进位值和字元间的空白 */ for ( j = 0; j < 16; j++ ) { totalchar--; if ( totalchar < 0 ) printf(" "); /* 输出完成后用空白取代 */ else if ( isprint(buffer[i*16+j]) ) printf("%c",buffer[i*16+j]);/*输出字元*/ else /* 非字元则用 . 取代 */ printf("."); } printf("\n"); } printf("\n"); } close(fd); return 0; } (请用平面式 左到右 来想像档案中的位元组) 首先,磁区开始 因为 lseek(fd,pos,SEEK_SET) 而被设定 位移量 将从 SEEK_SET 当作基准点 磁区为什么要乘以 64? 因为他设定 buffer 一次要读 64 个位元组,当然也可以设定不要乘以 64 那么你输入磁区的时候就要打 64, 128, 192 岂不是很麻烦 读了 档案中某一块 64 的位元组后,接下来程式就是要显示 这64个位元组资料 是什么东西 他很想要模拟 UltraEdit 那样一行显示 16 个 16进位码 请注意底下的像是 FFD8 其实是 2 个位元组 组成的,原本是要显示 FF D8 但我想把他合在一起 十六进位的 FF 就是 十进位的 255 刚好是 2 的 8 次方-1 ,这就是 1 位元组有8个位元装得下最大的数字 (unsigned) (最小是 0) 至于接下来除以 16 就是不想要一行 显示 64 个,这样会超出视窗范围 因此他将 64 切成 4 块 (显示会显示 4 行) 来显示,64 / 4 = 16 ,这就是 16 的由来 至于 i*16+j 则是在 64 位元组内 的 位移量 在回圈内 i*16+j 跑起来将会从 0~63 刚好一次读一个位元组 至于达到 EOF 时候,buffer[i*16+j] 内是没有读到东西的 则将会显示空白 你可以把 RJ TextEd 与 程式的结果来对照,请输入 磁区 0 来比对比较轻松 将发现 16进位码是 一模一样 很有趣的,磁区2 里面会看到 Adobe Photoshop CS2 甚至还有时间 他这张桌布是用哪个软体编辑的还有储存时间 都很明显 Chromatic_link_by_k3_studio.jpg 桌布下载:
x3 |