对于一个dat的二进制文件,现在我们来读取分析其内容
1. fseek(fp,0L,SEEK_END); /* 定位到文件末尾 */ long len =ftell(fp); printf("len:%ld\n",len);
函数 ftell() 用于得到文件位置指针当前位置相对于文件首的偏移字节数。结合fseek,可以得到文件内容长度。单位为字节。
每次操作之前注意此时文件指针位置。
2.fread (void *ptr, size_t size, size_t nmemb, FILE *stream)
注意void *ptr,是内存地址,不是变量!
short buffer[2000]={1}; /* 打开文件用于读写 */ /* 读取并显示数据 */ fread(buffer, 2, 1, fp); printf("%hd\n", buffer[0]);
short b; short *a=&b ; /* 读取并显示数据 */ fread(a, 2, 1, fp); printf("%hd\n", b);
类似的,我们可以直接:
fread(&b, 2, 1, fp);
printf("%hd\n", b);
3.注意判断自身读取文件时候是处于大端模式还是小端模式,而数据文件又是什么模式!
4.我们可以设施主函数参数,用来携带路径使用:
int main(int argc, char* argv[]){ FILE *fp; /* 打开文件用于读写 */ scanf("%s",argv[0]); // fp = fopen("/MySpotFi/csi1022.dat", "rb"); fp=fopen(argv[0], "rb");}argc记录了用户在运行程序的命令行中输入的参数的个数。 arg[]指向的数组中至少有一个字符指针,即arg[0].他通常指向程序中的可执行文件的文件名。在有些版本的编译器中还包括程序 文件所在的路径。
>./test 这个argc的值是1 但是 >./test myarg1 myarg2
这里argc的值是3。也就是 命令名 加上两个参数 myarg1 myarg2,一共三个参数 char *argv[] 这用来取得你所输入的参数 >./test 这个时候,argc的值是1,argv[0]的值是 "test" >./test myarg1 myarg2 这个时候,argc的值是3,argc[0]的值是"test",argc[1]的值是"myarg1",argc[2]的值是"myarg2"
1、int main(int argc,char *argv)与int main(int argc,char **argv)区别? int main(int argc,char *argv) argc: 整数,用来统计你运行程序时送给的命令行参数的个数 * argv: 字符串,用来存放指向你的字符串参数的,每一个元素指向一个参数 argv[0] 指向程序运行的全路径名 argv[1] 指向在DOS命令行中执行程序名后的第一个字符串 argv[2] 指向执行程序名后的第二个字符串 int main(int argc,char **argv) 相当于 int main(int argc,char *argv[ ] ) argc: 整数,用来统计你运行程序时送给的命令行参数的个数 * argv: 字符串,用来存放指向你的字符串参数的,每一个元素指向一个参数 argv[1] 指向在DOS命令行中执行程序名后的第一个字符串的指针 argv[2] 指向执行程序名后的第二个字符串的指针 在int main(int argc,char **argv)中 argv[1]是一个指针,存的内容是一个地址,而在int main(int argc,char *argv)中argv[1]是一个数组元素
这段来自 https://www.cnblogs.com/ruixingw/p/3705918.html
5.Mac os下编译后产生的Unix文件,只能再MacOS下使用,实测交给另一台macOS可以运行,报没有相关三方库。但是给Ubuntu上使用时候却无法识别,报commend not found
这是因为MacOS下生成的Unix可执行文件和Ubuntu下并不可以通用,不仅如此,在从MacOS下拷贝静态库的.a文件到Ubuntu下也不可以使用,虽然Ubuntu下也有.a文件,但是和MacOS下的.a并不同,也许是封装格式原因,有待后续了解。
6.注意我们其实也可以按字节读取,
short field_len=0; short code=0; bool flag=EndianInThere();
while(condition){ fread(&field_len, 2, 1, fp);//已知两字节存文件长度 if(!flag){//对于判断后的大小端,针对已知存储,调整高低8位 field_len=((field_len&0x00ff)<<8)+((field_len&0xff00)>>8); } fread(&code, 1, 1, fp);//只读一个字节,只是short使用,我小端模式下,低8位是数据,高8位就是0了。
判断大小端:
bool EndianInThere(){ union NUM{ int a; char b; }num; num.a = 0x1234; if( num.b == 0x12 ){ //printf(" This is big-endian,return true flag; \n"); return true; }else if( num.b == 0x34){ //printf("This is little-endian,return false flag;\n"); return false; }else{ printf("不是大端也不是小端,你这个方法有误啊\n"); exit(1); } }
7.值得中注意的的是,如果你要立刻使用刚刚传输过来的文件,需要fflush();将内存中内容刷新到硬盘,这样,read才是文件内容。