对于一个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才是文件内容。