0%

中科院实习——文件提取与保存

第一个任务:关于数据的读取与保存的任务。
使用C语言对二进制文件进行读取:找到包头后找到第80位数据,将获得的二进制文件转换为角度。

任务简介

第一个任务是,有这样一组文件,文件的内容是采集的轮船惯导数据。需要将轮船的航向、俯摇及横摇数据提取出来转换成角度加以分析。

任务拆解

其实这个任务就是简单的文件进行读取以及保存。用惯了python的调用pandas库进行读取,在C语言中,文件的读取相对复杂一点。

  1. 文件的打开
    fopen():打开文件
  2. 文件的关闭
    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,也就是位数不够,低位扩充的是符号位。

-------------本文结束感谢您的阅读-------------