eric2013 发表于 2023-2-14 11:42:15

Excel的CSV格式文件读写实现



逗号是分割,换行换列是下一行,创建的文件可以使用excel方便的打开

下面是FlashFS的,使用FatFS,FileX也是类似的;

/*
*********************************************************************************************************
*        函 数 名: WriteCSVFile
*        功能说明: 写数据到CSV文件中
*        形    参: _path,U盘,SD卡和NAND
*        返 回 值: 无
*********************************************************************************************************
*/
static void WriteCSVFile(char *_path)
{
        const uint8_t WriteText[] = {"记录时间,标号,记录数值一,记录数值二\r\n"};
        FILE *fout;
        uint8_t result;
        static uint16_t i = 1;
        static uint8_t ucFirstRunFlag = 0;
        char namepath;

    result = finit(_path);
        if(result != NULL)
        {
                /* 如果挂载失败,务必不要再调用FlashFS的其它API函数,防止进入硬件异常 */
                printf("初始化文件系统失败 (%s)\r\n", ReVal_Table);
                return;      
        }
        else
        {
                printf("初始化文件系统成功 (%s)\r\n", ReVal_Table);
        }
   
        /* 加载 */
        result = fmount(_path);
       
        if(result != NULL)
        {
                /* 如果挂载失败,务必不要再调用FlashFS的其它API函数,防止进入硬件异常 */
                printf("挂载文件系统失败 (%s)\r\n", ReVal_Table);
                goto access_fail;
        }
        else
        {
                printf("挂载文件系统成功 (%s)\r\n", ReVal_Table);
        }
        printf("------------------------------------------------------------------\r\n");
       
        /**********************************************************************************************************/
        /*
          1. 打开文件record.csv,如果没有此文件会自动创建。
          2. 第二个参数表示向此文件写数据都从尾部开始添加。
        */
        sprintf(namepath, "%s\\record.csv", _path);
        fout = fopen (namepath, "a");
        if (fout != NULL)
        {
                printf("打开文件M0:\\record.csvt成功,如果没有此文件会自动创建\r\n");
               
                /* 写数据,如果是第一次写数据,先写CSV文件的表项的题目,以后写数据不再需要写此表项 */
                if(ucFirstRunFlag == 0)
                {
                        fprintf(fout, (char *)WriteText);
                        ucFirstRunFlag = 1;
                }
               
                /* 依次写5行数据 */
                fprintf (fout, "%d, %d, %f\r\n", i, i*5, i*5.55f);
               
                i++;
                fprintf (fout, "%d, %d, %f\r\n", i, i*5, i*5.55f);
               
                i++;
                fprintf (fout, "%d, %d, %f\r\n", i, i*5, i*5.55f);
               
                i++;
                fprintf (fout, "%d, %d, %f\r\n", i, i*5, i*5.55f);
               
                i++;
                fprintf (fout, "%d, %d, %f\r\n", i, i*5, i*5.55f);
                i++;
               
                /* 使用函数ferror检测是否发生过错误 */
                if (ferror(fout) != NULL)
                {
                        printf("写入内容失败\r\n");
                }
                else
                {
                        printf("写入内容成功\r\n");       
                }
               
                /* 关闭文件 */
                fclose(fout);
        }
        else
        {
                printf("打开文件M0:\\record.csv失败\r\n");
        }

access_fail:       
        /* 卸载 */
        result = funmount(_path);
        if(result != NULL)
        {
                printf("卸载文件系统失败\r\n");
        }
        else
        {
                printf("卸载文件系统成功\r\n");
        }
   
    result = funinit(_path);
        if(result != NULL)
        {
                printf("复位文件系统失败 (%s)\r\n", ReVal_Table);
        }
        else
        {
                printf("复位文件系统成功 (%s)\r\n", ReVal_Table);
        }

        printf("------------------------------------------------------------------\r\n");
}

/*
*********************************************************************************************************
*        函 数 名: ReadCSVFileData
*        功能说明: 读取CSV文件中的数据。
*        形    参: _path,U盘,SD卡和NAND
*        返 回 值: 无
*********************************************************************************************************
*/
static void ReadCSVFileData(char *_path)
{
        uint8_t Readbuf;
        FILE *fin;
        uint8_t result;
        char namepath;

    result = finit(_path);
        if(result != NULL)
        {
                /* 如果挂载失败,务必不要再调用FlashFS的其它API函数,防止进入硬件异常 */
                printf("初始化文件系统失败 (%s)\r\n", ReVal_Table);
                return;      
        }
        else
        {
                printf("初始化文件系统成功 (%s)\r\n", ReVal_Table);
        }
   
        /* 加载 */
        result = fmount(_path);
       
        if(result != NULL)
        {
                /* 如果挂载失败,务必不要再调用FlashFS的其它API函数,防止进入硬件异常 */
                printf("挂载文件系统失败 (%s)\r\n", ReVal_Table);
                goto access_fail;
        }
        else
        {
                printf("挂载文件系统成功 (%s)\r\n", ReVal_Table);
        }
        printf("------------------------------------------------------------------\r\n");
       
        /**********************************************************************************************************/
        /* 打开record.csv文件 */
        sprintf(namepath, "%s\\record.csv", _path);
        fin = fopen (namepath, "r");
        if (fin != NULL)
        {
                printf("打开文件M0:\\record.csv成功\r\n");
               
                /* 将所有数据都读出来,使用fgets函数的好处就是可以一行一行的读取,因为此函数遇到'\n'换行符就会停止读取 */
                while (fgets((char *)Readbuf, sizeof(Readbuf), fin) != NULL)
                {
                        printf("%s", Readbuf);       
                }
               
                /* 使用函数ferror检测是否发生过错误 */
                if (ferror(fin) != NULL)
                {
                        printf("读出内容失败\r\n");
                }
                else
                {
                        printf("record.csv里面的内容全部正确读出\r\n");       
                }
               
                /* 关闭文件 */
                fclose(fin);
        }
        else
        {
                printf("打开文件M0:\\record.csv失败\r\n");
        }
       
access_fail:
        /* 卸载 */
        result = funmount(_path);
        if(result != NULL)
        {
                printf("卸载文件系统失败\r\n");
        }
        else
        {
                printf("卸载文件系统成功\r\n");
        }
   
    result = funinit(_path);
        if(result != NULL)
        {
                printf("复位文件系统失败 (%s)\r\n", ReVal_Table);
        }
        else
        {
                printf("复位文件系统成功 (%s)\r\n", ReVal_Table);
        }

        printf("------------------------------------------------------------------\r\n");
}

Zilch0 发表于 2023-12-19 18:55:32

想问一下,如果是读写单片机SD卡中的csv文件,_path怎么获得呢?

eric2013 发表于 2023-12-20 09:16:58

Zilch0 发表于 2023-12-19 18:55
想问一下,如果是读写单片机SD卡中的csv文件,_path怎么获得呢?

这个是用户设置的读写路径。
页: [1]
查看完整版本: Excel的CSV格式文件读写实现