第一个任务:关于数据的读取与保存的任务。
使用C语言对二进制文件进行读取:找到包头后找到第80位数据,将获得的二进制文件转换为角度。
任务简介
第一个任务是,有这样一组文件,文件的内容是采集的轮船惯导数据。需要将轮船的航向、俯摇及横摇数据提取出来转换成角度加以分析。
任务拆解
其实这个任务就是简单的文件进行读取以及保存。用惯了python的调用pandas库进行读取,在C语言中,文件的读取相对复杂一点。
- 文件的打开
fopen():打开文件 - 文件的关闭
fclose():关闭文件
3.文件的读写
fgetc():读取一个字符
fputc():写入一个字符
fgets():读取一个字符串
fputs():写入一个字符串
fprintf():写入格式化数据
fscanf():格式化读取数据
fread():二进制输入
fwrite():二进制输出
4.文件状态检查
feof():文件是否结束
ferror():文件读/写是否出错
clearerr():清除文件错误标志
ftell():文件指针的当前位置
5.文件指针定位
rewind():把文件指针移到开始处
fseek():重定位文件指针
6.参数解释:
“r”:以只读的形式打开文本文件(不存在则出错)
“w”:以只写的形式打开文本文件(若不存在则新建,反之,则从文件起始位置写,覆盖原内容)
“a”:以追加的形式打开文本文件(若不存在,则新建;反之,在原文件后追加)
“r+”:以读写的形式打开文本文件(读时,从头开始;写时,新数据只覆盖所占的空间)
“wb”:以只写的形式打开二进制文件
“rb”:以只读的形式打开二进制文件
“ab”:以追加的形式打开一个二进制文件
“rb+”:以读写的形式打开二进制文件。
“w+”:首先建立一个新文件,进行写操作,然后从头开始读(若文件存在,原内容将全部消失)
“a+”:功能与”a”相同。只是在文件尾部追加数据后,可以从头开始读
“wb+”:功能与”w+”相同。只是在读写时,可以由位置函数设置读和写的起始位置
“ab+”:功能与”a+”相同。只是在文件尾部追加数据之后,可以由位置函数设置开始读的起始位置
7.打开文件
FILE *fopen( const char *filename, const char *mode );
filename:文件的路径
mode:打开模式
任务执行
一开始我使用了字符读取函数,但是发现无法读取我们的文件。之后知道文件保存时是转为二进制保存的,因此本文档是一个二进制保存的文件。
修改后具体代码如下:
# include <stdio.h>
# include <stdint.h>
void saveDataToCSV(const char* filename, float a, float b, float c) {
// 打开文件用于追加写入
FILE* file = fopen(filename, "a");
if (file == NULL) {
printf("can't open!\n");
return;
}
// 如果文件为空,则写入列名
long fileSize;
fseek(file, 0, SEEK_END);
fileSize = ftell(file);
if (fileSize == 0) {
fprintf(file, "v,x,y\n");
}
// 写入数据到文件
fprintf(file, "%f,%f,%f\n", a, b, c);
// 关闭文件
fclose(file);
}
int main() {
FILE *file;
uint8_t buffer[1024];
size_t bytesRead;
int found = 0;
int position = 0;
short a;
unsigned short b;
float angel;
float angel1;
float angel2;
// 打开文件
file = fopen("F:/7_3/data/H16_0-2023-06-13-11-41-09.IRDV", "rb");
if (file == NULL) {
printf("No file\n");
return 1;
}
// 读取文件数据
while (!feof(file)) {
bytesRead = fread(buffer, sizeof(uint8_t), sizeof(buffer), file);
for (size_t i = 0; i < bytesRead; i++) {
if (found) {
position++;
if (position == 81*2-2 ) {
b = ((short)buffer[i+1] << 8) |(short) buffer[i];
angel = b * 360.0 / 65535;
if (angel<180){
angel = angel + 360.0;
}
printf("Angle = %.2f degrees\n", angel);
}
if (position == 82*2-2 ) {
a = ((short)buffer[i+1] << 8) |(short) buffer[i];
angel1 =a * 180.0 / 32767;
printf("Angle = %.2f degrees\n", angel1);
}
if (position == 83*2-2 ) {
a = ((short)buffer[i+1] << 8) |(short) buffer[i];
angel2 = a * 180.0 / 32767;
printf("Angle = %.2f degrees\n", angel2);
printf("-----------------------------------\n");
found = 0;
position = 0;
saveDataToCSV("F:/Project/Angel_get/Angel_get/data1.csv", angel, angel1,angel2);
}
} else if (buffer[i] == 0x3D && i + 3 < bytesRead && buffer[i + 1] == 0xFE &&
buffer[i + 2] == 0xFA && buffer[i + 3] == 0xA5) {
found = 1; //找到开始的位置,标志位置为1,开始往后计数。
}
}
}
// 如果未找到数据
//printf("No find\n");
fclose(file);
return 0;
}
(short)buffer[i+1] << 8这里要注意一个有符号short型在左移八位时,比如#0X80左移后低位会变成FF,也就是位数不够,低位扩充的是符号位。