1. CSV文件的格式
CSV表格的基本格式为:
字符串,字符串,...,字符串\r\n
字符串,字符串,...,字符串\r\n
...
字符串,字符串,...,字符串\r\n
例如,对于如下表格:
1 2 3
1 2 3
1 2 3
当采用%5.3f格式存储为CSV文件时,存储的数据为:
'1' '.' '0' '0' '0' ',' '2' '.' '0' '0' '0' '3' '.' '0' '0' '0' '\r' '\n'
'1' '.' '0' '0' '0' ',' '2' '.' '0' '0' '0' '3' '.' '0' '0' '0' '\r' '\n'
'1' '.' '0' '0' '0' ',' '2' '.' '0' '0' '0' '3' '.' '0' '0' '0' '\r' '\n'
本文所述读写CSV文件方法所采用的CSV文件将严格按照上述方式存储。特别地,对于读取CSV文件的情况,数据接受以科学计数法形式的字符串存储。
2. 基于FATFS文件系统读写CSV文件
STM32移植FATFS文件系统见SPI驱动SD卡及FATFS移植。以下给出关键文件代码:
- ucsv.h
/**
*******************************************************************************
* @file ucsv.h
* @author xixizhk
*******************************************************************************
* @version V2022 @ Nov 11, 2022 \n
* Initial version.
*******************************************************************************
*/
/* Define to prevent recursive inclusion **************************************/
#ifndef _UCSV_H
#define _UCSV_H
#ifdef __cplusplus
extern "C" {
#endif
/**
*******************************************************************************
* @addtogroup Includes
* @{
*/
#include "stdint.h"
/**
* @}
*/
/**
*******************************************************************************
* @addtogroup Definitions
* @{
*/
/**
* @}
*/
/**
*******************************************************************************
* @addtogroup Types
* @{
*/
/**
* @}
*/
/**
*******************************************************************************
* @addtogroup Constants
* @{
*/
/**
* @}
*/
/**
*******************************************************************************
* @addtogroup Variables
* @{
*/
/**
* @}
*/
/**
*******************************************************************************
* @addtogroup Macros
* @{
*/
/**
* @}
*/
/**
*******************************************************************************
* @addtogroup Functions
* @{
*/
int ucsv_read(char* _path, float* _tab, unsigned int _row, unsigned int _col);
int ucsv_write(char* _path, float* _tab, unsigned int _row, unsigned int _col);
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* _UCSV_H */
/**************************** ALL RIGHTS RESERVED *****************************/
- ucsv.c
/**
*******************************************************************************
* @file ucsv.c
* @author xixizhk
*******************************************************************************
* @version V2022 @ Nov 11, 2022 \n
* Initial version.
*******************************************************************************
*/
/**
*******************************************************************************
* @addtogroup Includes
* @{
*/
#include "ucsv.h"
#include "ff.h"
#include "stdio.h"
/**
* @}
*/
/**
*******************************************************************************
* @addtogroup Definitions
* @{
*/
/**
* @}
*/
/**
*******************************************************************************
* @addtogroup Types
* @{
*/
/**
* @}
*/
/**
*******************************************************************************
* @addtogroup Constants
* @{
*/
/**
* @}
*/
/**
*******************************************************************************
* @addtogroup Variables
* @{
*/
static FATFS csvfs;
static FIL csvfile;
static FRESULT csvfres;
static UINT csvbn;
static char csvbuffer[4096];
/**
* @}
*/
/**
*******************************************************************************
* @addtogroup Macros
* @{
*/
/**
* @}
*/
/**
*******************************************************************************
* @addtogroup Functions
* @{
*/
/**
* @brief Read specified .csv file into specified table.
* @param _path [In]: path of the file.
* @param _tab [Out]: point to the 2-D table for read data.
* @param _row [In]: number of row of the table.
* @param _col [In]: number of column of the table.
* @return 0 if successful.
*/
int ucsv_read(char* _path, float* _tab, unsigned int _row, unsigned int _col)
{
unsigned int i, j, k;
char str_data[64];
char *pbuffer;
char diskletter[2];
diskletter[0] = _path[0];
diskletter[1] = '\0';
csvfres = f_mount(&csvfs, diskletter, 1);
if (csvfres != FR_OK)
{
f_mount(0, "", 1);
return 1;
}
csvfres = f_open(&csvfile, _path, FA_READ);
if (csvfres != FR_OK)
{
f_close(&csvfile);
f_mount(0, "", 1);
return 2;
}
csvbn = f_size(&csvfile);
if (csvbn > sizeof(csvbuffer))
{
f_close(&csvfile);
f_mount(0, "", 1);
return 3;
}
csvfres = f_read(&csvfile, csvbuffer, csvbn, &csvbn);
pbuffer = csvbuffer;
for (i = 0; i < _row; i++)
{
for (j = 0; j < _col; j++)
{
for (k = 0; k < sizeof(str_data); k++)
{
if ((*pbuffer == ',') || (*pbuffer == '\r'))
{
str_data[k] = '\r';
str_data[k + 1] = '\n';
pbuffer = pbuffer + 1;
break;
}
else
{
str_data[k] = *pbuffer;
pbuffer = pbuffer + 1;
}
}
sscanf(str_data, "%f", _tab);
_tab = _tab + 1;
}
pbuffer = pbuffer + 1;
}
f_close(&csvfile);
f_mount(0, "", 1);
return 0;
}
/**
* @brief Write specified table to specified .csv file.
* @param _path [In]: path of the file.
* @param _tab [Out]: point to the 2-D table for read data.
* @param _row [In]: number of row of the table.
* @param _col [In]: number of column of the table.
* @return 0 if successful.
*/
int ucsv_write(char* _path, float* _tab, unsigned int _row, unsigned int _col)
{
unsigned int i, j, n;
char diskletter[2];
diskletter[0] = _path[0];
diskletter[1] = '\0';
csvfres = f_mount(&csvfs, diskletter, 1);
if (csvfres != FR_OK)
{
f_mount(0, "", 1);
return 1;
}
csvfres = f_open(&csvfile, _path, FA_CREATE_ALWAYS | FA_WRITE |FA_READ);
if (csvfres != FR_OK)
{
f_close(&csvfile);
f_mount(0, "", 1);
return 2;
}
for (i = 0; i < _row; i++)
{
for (j = 0; j < _col; j++)
{
n = snprintf(csvbuffer, sizeof(csvbuffer), "%8.4f", *_tab);
if (j < _col - 1)
{
csvbuffer[n] = ',';
n = n + 1;
}
else
{
csvbuffer[n] = '\r';
csvbuffer[n + 1] = '\n';
n = n + 2;
}
f_write(&csvfile, csvbuffer, n, &n);
_tab = _tab + 1;
}
}
f_close(&csvfile);
f_mount(0, "", 1);
return 0;
}
/**
* @}
*/
/**************************** ALL RIGHTS RESERVED *****************************/
3. 函数使用说明
3.1 读取CSV文件至二维数浮点数组
- Step 1: 定义数组,例如:
#define _ROW_NBR (10U)
#define _COL_NBR (10U)
float table[_ROW_NBR][_COL_NBR];
- Step 2: 调用
int ucsv_read(char* _path, float* _tab, unsigned int _row, unsigned int _col)函数将指定的CSV文件读取至二维浮点数组中(盘符号是必须的),例如:
ucsv_read("0:table.csv", &(table[0][0]), _ROW_NBR, _COL_NBR);
3.2 将二维浮点数组写入CSV文件
- Step 1: 定义数组,例如:
#define _ROW_NBR (10U)
#define _COL_NBR (10U)
float table[_ROW_NBR][_COL_NBR];
- Step 2: 调用
int ucsv_write(char* _path, float* _tab, unsigned int _row, unsigned int _col)函数将二维数浮点数组写入指定的CSV文件中(盘符号是必须的),例如:
ucsv_write("0:table.csv", &(table[0][0]), _ROW_NBR, _COL_NBR);
Provided by 昨夜三更雨, see https://www.cnblogs.com/zysgy/p/16920289.html
浙公网安备 33010602011771号