LabWindows/CVI 文本文件读写指南
基于 LabWindows/CVI 的完整文本文件读写解决方案,包含ANSI/Unicode 编码支持、大文件处理、CSV/XML/JSON 解析、实时数据记录等工业级功能。
一、核心文件I/O函数概览
| 函数类型 | ANSI C 函数 | CVI 专用函数 | 特点 |
|---|---|---|---|
| 打开/关闭 | fopen/fclose |
OpenFile/CloseFile |
CVI函数有更多选项 |
| 读取 | fread/fgets |
ReadLine/ReadFile |
CVI支持Unicode |
| 写入 | fwrite/fprintf |
WriteFile/WriteLine |
带错误处理 |
| 定位 | fseek/ftell |
SetFilePos/GetFilePos |
位置控制 |
| 属性 | stat |
GetFileInfo |
文件信息 |
二、基本文本文件读写
1、创建新文件并写入
// 基本文件写入示例
#include <formatio.h>
#include <utility.h>
#include <ansi_c.h>
int WriteTextFile_Basic(void)
{
int fileHandle;
int status;
char filename[256] = "data.txt";
// 1. 创建/打开文件 (Write Only, Create if not exist)
fileHandle = OpenFile(filename, VAL_WRITE_ONLY, VAL_OPEN_AS_IS, VAL_ASCII);
if (fileHandle <= 0) {
MessagePopup("错误", "无法创建文件: %s", filename);
return -1;
}
// 2. 写入文本数据
char buffer[512];
double temperature = 25.6;
int sensor_id = 1;
// 方法1: 使用Fmt函数格式化
Fmt(buffer, "%s<T>写入时间: %s</T>\n",
"<Data>\n", GetCurrentDateTimeString());
status = WriteFile(fileHandle, buffer, strlen(buffer));
// 方法2: 写入格式化数据
Fmt(buffer, "%s<Temperature>%.2f</Temperature>\n",
"", temperature);
WriteFile(fileHandle, buffer, strlen(buffer));
Fmt(buffer, "%s<SensorID>%d</SensorID>\n", "", sensor_id);
WriteFile(fileHandle, buffer, strlen(buffer));
// 方法3: 写入CSV格式
Fmt(buffer, "Time,Temperature,SensorID\n");
WriteFile(fileHandle, buffer, strlen(buffer));
Fmt(buffer, "%s,%.2f,%d\n", GetCurrentDateTimeString(), temperature, sensor_id);
WriteFile(fileHandle, buffer, strlen(buffer));
// 3. 关闭文件
CloseFile(fileHandle);
return 0;
}
2、读取文本文件
// 读取文本文件
int ReadTextFile_Basic(char *filename)
{
int fileHandle;
int bytesRead;
char buffer[1024];
// 1. 打开文件
fileHandle = OpenFile(filename, VAL_READ_ONLY, VAL_OPEN_AS_IS, VAL_ASCII);
if (fileHandle <= 0) {
MessagePopup("错误", "无法打开文件: %s", filename);
return -1;
}
// 2. 获取文件大小
long fileSize = 0;
GetFileSize(filename, &fileSize);
printf("文件大小: %ld 字节\n", fileSize);
// 3. 逐行读取
int lineNum = 0;
printf("=== 文件内容 ===\n");
while (1) {
// 读取一行(遇到换行符停止)
bytesRead = ReadLine(fileHandle, buffer, sizeof(buffer)-1);
if (bytesRead <= 0) {
break; // 文件结束
}
buffer[bytesRead] = '\0'; // 确保字符串结束
// 显示行号和内容
printf("Line %d: %s\n", ++lineNum, buffer);
// 可以在这里解析内容
ParseLineContent(buffer, lineNum);
}
// 4. 关闭文件
CloseFile(fileHandle);
return lineNum; // 返回读取的行数
}
三、高级文件操作
1、带缓冲的大文件读写
// 高效大文件读取
int ReadLargeFile_Efficient(char *filename)
{
int fileHandle;
long bufferSize = 4096; // 4KB缓冲区
char *buffer = NULL;
int totalBytesRead = 0;
buffer = malloc(bufferSize);
if (!buffer) {
MessagePopup("错误", "内存分配失败");
return -1;
}
fileHandle = OpenFile(filename, VAL_READ_ONLY, VAL_OPEN_AS_IS, VAL_ASCII);
if (fileHandle <= 0) {
free(buffer);
return -1;
}
// 设置缓冲区
SetFileBuffer(fileHandle, buffer, bufferSize);
while (1) {
int bytesRead = ReadFile(fileHandle, buffer, bufferSize-1);
if (bytesRead <= 0) {
break; // 文件结束
}
totalBytesRead += bytesRead;
buffer[bytesRead] = '\0';
// 处理读取的数据
ProcessBuffer(buffer, bytesRead);
// 显示进度
if (totalBytesRead % (10*1024*1024) == 0) { // 每10MB显示一次
printf("已读取: %.2f MB\n", totalBytesRead / 1024.0 / 1024.0);
}
}
// 清理
CloseFile(fileHandle);
free(buffer);
printf("总共读取: %d 字节\n", totalBytesRead);
return totalBytesRead;
}
2、二进制+文本混合写入
// 混合数据记录(文本头 + 二进制数据)
int WriteMixedDataFile(char *filename, double *data, int dataCount)
{
int fileHandle;
char header[256];
// 1. 打开文件
fileHandle = OpenFile(filename, VAL_WRITE_ONLY, VAL_TRUNCATE, VAL_BINARY);
if (fileHandle <= 0) {
return -1;
}
// 2. 写入文本头部信息
Fmt(header, "=== 数据文件头 ===\n");
WriteFile(fileHandle, header, strlen(header));
Fmt(header, "创建时间: %s\n", GetCurrentDateTimeString());
WriteFile(fileHandle, header, strlen(header));
Fmt(header, "数据点数: %d\n", dataCount);
WriteFile(fileHandle, header, strlen(header));
Fmt(header, "采样率: 1000 Hz\n");
WriteFile(fileHandle, header, strlen(header));
Fmt(header, "=== 二进制数据开始 ===\n");
WriteFile(fileHandle, header, strlen(header));
// 3. 写入二进制数据
int bytesWritten = WriteFile(fileHandle, (char*)data, dataCount * sizeof(double));
if (bytesWritten != dataCount * sizeof(double)) {
MessagePopup("警告", "数据写入不完整");
}
// 4. 写入结束标记
Fmt(header, "\n=== 文件结束 ===\n");
WriteFile(fileHandle, header, strlen(header));
CloseFile(fileHandle);
return bytesWritten;
}
四、CSV文件处理
1、CSV写入类
// csv_handler.h
#ifndef CSV_HANDLER_H
#define CSV_HANDLER_H
#include <formatio.h>
#include <ansi_c.h>
typedef struct {
int fileHandle;
char filename[256];
char delimiter;
int columnCount;
char **columnHeaders;
} CSVFile;
// 函数声明
CSVFile* CSV_Create(const char *filename, char delimiter);
int CSV_AddHeaders(CSVFile *csv, const char *headers[], int count);
int CSV_WriteRow(CSVFile *csv, ...);
int CSV_WriteRowArray(CSVFile *csv, double *values, int count);
int CSV_Close(CSVFile *csv);
#endif
// csv_handler.c
#include "csv_handler.h"
#include <stdarg.h>
#include <userint.h>
// 创建CSV文件
CSVFile* CSV_Create(const char *filename, char delimiter)
{
CSVFile *csv = (CSVFile*)malloc(sizeof(CSVFile));
if (!csv) return NULL;
strcpy(csv->filename, filename);
csv->delimiter = delimiter;
csv->columnCount = 0;
csv->columnHeaders = NULL;
// 创建文件
csv->fileHandle = OpenFile(filename, VAL_WRITE_ONLY, VAL_TRUNCATE, VAL_ASCII);
if (csv->fileHandle <= 0) {
free(csv);
return NULL;
}
return csv;
}
// 添加表头
int CSV_AddHeaders(CSVFile *csv, const char *headers[], int count)
{
char buffer[1024] = "";
char temp[256];
csv->columnCount = count;
csv->columnHeaders = (char**)malloc(count * sizeof(char*));
for (int i = 0; i < count; i++) {
// 复制表头
csv->columnHeaders[i] = strdup(headers[i]);
// 构建表头行
if (i > 0) {
strcat(buffer, ",");
}
strcat(buffer, headers[i]);
}
strcat(buffer, "\n");
// 写入表头
return WriteFile(csv->fileHandle, buffer, strlen(buffer));
}
// 写入一行数据(可变参数)
int CSV_WriteRow(CSVFile *csv, ...)
{
va_list args;
char buffer[1024] = "";
char temp[256];
va_start(args, csv);
for (int i = 0; i < csv->columnCount; i++) {
if (i > 0) {
strcat(buffer, ",");
}
// 根据表头类型处理数据
if (strstr(csv->columnHeaders[i], "Time") ||
strstr(csv->columnHeaders[i], "Date")) {
// 时间类型
char *timeStr = va_arg(args, char*);
sprintf(temp, "\"%s\"", timeStr);
}
else if (strstr(csv->columnHeaders[i], "Value") ||
strstr(csv->columnHeaders[i], "Data")) {
// 数值类型
double value = va_arg(args, double);
Fmt(temp, "%.6f", value);
}
else {
// 字符串类型
char *str = va_arg(args, char*);
sprintf(temp, "\"%s\"", str);
}
strcat(buffer, temp);
}
va_end(args);
strcat(buffer, "\n");
return WriteFile(csv->fileHandle, buffer, strlen(buffer));
}
// 关闭CSV文件
int CSV_Close(CSVFile *csv)
{
if (!csv) return -1;
// 释放表头内存
for (int i = 0; i < csv->columnCount; i++) {
free(csv->columnHeaders[i]);
}
free(csv->columnHeaders);
// 关闭文件
int result = CloseFile(csv->fileHandle);
free(csv);
return result;
}
2、CSV读取解析
// 读取和解析CSV文件
int ParseCSVFile(char *filename)
{
int fileHandle = OpenFile(filename, VAL_READ_ONLY, VAL_OPEN_AS_IS, VAL_ASCII);
if (fileHandle <= 0) return -1;
char line[1024];
int rowCount = 0;
// 读取表头
if (ReadLine(fileHandle, line, sizeof(line)) > 0) {
printf("表头: %s\n", line);
// 解析表头
char *headers[20];
int colCount = ParseCSVLine(line, headers, 20, ',');
printf("找到 %d 列\n", colCount);
}
// 读取数据行
while (ReadLine(fileHandle, line, sizeof(line)) > 0) {
rowCount++;
// 解析CSV行
char *fields[20];
int fieldCount = ParseCSVLine(line, fields, 20, ',');
// 处理数据
for (int i = 0; i < fieldCount; i++) {
// 移除引号
char *field = fields[i];
if (field[0] == '"' && field[strlen(field)-1] == '"') {
field[strlen(field)-1] = '\0';
field++;
}
printf("行%d 列%d: %s\n", rowCount, i+1, field);
}
}
CloseFile(fileHandle);
printf("总共 %d 行数据\n", rowCount);
return rowCount;
}
// 解析CSV行
int ParseCSVLine(char *line, char *fields[], int maxFields, char delimiter)
{
int fieldCount = 0;
char *start = line;
int inQuotes = 0;
for (char *p = line; *p && fieldCount < maxFields; p++) {
if (*p == '"') {
inQuotes = !inQuotes;
}
else if (*p == delimiter && !inQuotes) {
*p = '\0';
fields[fieldCount++] = start;
start = p + 1;
}
}
// 最后一个字段
if (fieldCount < maxFields) {
fields[fieldCount++] = start;
}
return fieldCount;
}
五、实时数据记录器
// data_logger.h
#ifndef DATA_LOGGER_H
#define DATA_LOGGER_H
#include <ansi_c.h>
#include <cvirte.h>
typedef enum {
LOG_FORMAT_CSV = 0,
LOG_FORMAT_XML,
LOG_FORMAT_JSON,
LOG_FORMAT_TXT
} LogFormat_t;
typedef struct {
char filename[256];
LogFormat_t format;
int maxFileSize; // MB
int currentSize;
int fileHandle;
int enableTimestamp;
int autoFlush;
} DataLogger;
// 函数声明
DataLogger* Logger_Create(const char *baseName, LogFormat_t format);
int Logger_WriteData(DataLogger *logger, double *data, int count, const char *tag);
int Logger_WriteEvent(DataLogger *logger, const char *event, int severity);
int Logger_CheckRotation(DataLogger *logger);
int Logger_Close(DataLogger *logger);
#endif
// data_logger.c
#include "data_logger.h"
#include <time.h>
#include <sys/stat.h>
// 创建日志器
DataLogger* Logger_Create(const char *baseName, LogFormat_t format)
{
DataLogger *logger = (DataLogger*)malloc(sizeof(DataLogger));
if (!logger) return NULL;
// 生成带时间戳的文件名
time_t now = time(NULL);
struct tm *t = localtime(&now);
switch (format) {
case LOG_FORMAT_CSV:
sprintf(logger->filename, "%s_%04d%02d%02d_%02d%02d%02d.csv",
baseName, t->tm_year+1900, t->tm_mon+1, t->tm_mday,
t->tm_hour, t->tm_min, t->tm_sec);
break;
case LOG_FORMAT_XML:
sprintf(logger->filename, "%s_%04d%02d%02d.xml",
baseName, t->tm_year+1900, t->tm_mon+1, t->tm_mday);
break;
default:
sprintf(logger->filename, "%s_%04d%02d%02d.txt",
baseName, t->tm_year+1900, t->tm_mon+1, t->tm_mday);
}
logger->format = format;
logger->maxFileSize = 10; // 10MB
logger->currentSize = 0;
logger->enableTimestamp = 1;
logger->autoFlush = 1;
// 创建文件
logger->fileHandle = OpenFile(logger->filename, VAL_WRITE_ONLY,
VAL_TRUNCATE, VAL_ASCII);
if (logger->fileHandle <= 0) {
free(logger);
return NULL;
}
// 写入文件头
char header[512];
switch (format) {
case LOG_FORMAT_CSV:
strcpy(header, "Timestamp,Tag,Value1,Value2,Value3,Value4,Value5\n");
break;
case LOG_FORMAT_XML:
strcpy(header, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
strcat(header, "<DataLog>\n");
break;
case LOG_FORMAT_JSON:
strcpy(header, "{\n \"data\": [\n");
break;
}
WriteFile(logger->fileHandle, header, strlen(header));
return logger;
}
// 写入数据
int Logger_WriteData(DataLogger *logger, double *data, int count, const char *tag)
{
if (!logger || logger->fileHandle <= 0) return -1;
char buffer[1024];
char timeStr[64];
// 获取当前时间
if (logger->enableTimestamp) {
time_t now = time(NULL);
struct tm *t = localtime(&now);
sprintf(timeStr, "%02d:%02d:%02d", t->tm_hour, t->tm_min, t->tm_sec);
} else {
strcpy(timeStr, "");
}
// 根据格式写入
switch (logger->format) {
case LOG_FORMAT_CSV: {
// CSV格式: 时间,标签,值1,值2,...
sprintf(buffer, "%s,%s", timeStr, tag);
for (int i = 0; i < count && i < 5; i++) {
char temp[32];
sprintf(temp, ",%.6f", data[i]);
strcat(buffer, temp);
}
strcat(buffer, "\n");
break;
}
case LOG_FORMAT_XML: {
// XML格式
sprintf(buffer, " <Record>\n");
strcat(buffer, " <Time>"); strcat(buffer, timeStr); strcat(buffer, "</Time>\n");
strcat(buffer, " <Tag>"); strcat(buffer, tag); strcat(buffer, "</Tag>\n");
for (int i = 0; i < count; i++) {
char temp[64];
sprintf(temp, " <Value%d>%.6f</Value%d>\n", i+1, data[i], i+1);
strcat(buffer, temp);
}
strcat(buffer, " </Record>\n");
break;
}
case LOG_FORMAT_JSON: {
// JSON格式
static int firstRecord = 1;
if (!firstRecord) {
strcat(buffer, ",\n");
}
firstRecord = 0;
sprintf(buffer, " {\n");
sprintf(buffer + strlen(buffer), " \"time\": \"%s\",\n", timeStr);
sprintf(buffer + strlen(buffer), " \"tag\": \"%s\",\n", tag);
for (int i = 0; i < count; i++) {
char temp[64];
sprintf(temp, " \"value%d\": %.6f", i+1, data[i]);
strcat(buffer, temp);
if (i < count-1) strcat(buffer, ",");
strcat(buffer, "\n");
}
strcat(buffer, " }");
break;
}
default: {
// 文本格式
sprintf(buffer, "[%s] %s: ", timeStr, tag);
for (int i = 0; i < count; i++) {
char temp[32];
sprintf(temp, "%.6f ", data[i]);
strcat(buffer, temp);
}
strcat(buffer, "\n");
}
}
// 写入文件
int bytesWritten = WriteFile(logger->fileHandle, buffer, strlen(buffer));
logger->currentSize += bytesWritten;
// 自动刷新
if (logger->autoFlush) {
FlushFileBuffers(logger->fileHandle);
}
// 检查文件大小,需要时轮转
Logger_CheckRotation(logger);
return bytesWritten;
}
// 检查文件轮转
int Logger_CheckRotation(DataLogger *logger)
{
if (logger->currentSize < logger->maxFileSize * 1024 * 1024) {
return 0; // 不需要轮转
}
// 关闭当前文件
Logger_Close(logger);
// 创建新文件
char newName[256];
time_t now = time(NULL);
struct tm *t = localtime(&now);
sprintf(newName, "%s_%04d%02d%02d_%02d%02d%02d.%s",
"data_log", t->tm_year+1900, t->tm_mon+1, t->tm_mday,
t->tm_hour, t->tm_min, t->tm_sec,
(logger->format == LOG_FORMAT_CSV) ? "csv" :
(logger->format == LOG_FORMAT_XML) ? "xml" : "txt");
// 重命名原文件
rename(logger->filename, newName);
// 重新打开文件
logger->fileHandle = OpenFile(logger->filename, VAL_WRITE_ONLY,
VAL_TRUNCATE, VAL_ASCII);
logger->currentSize = 0;
return 1;
}
// 关闭日志器
int Logger_Close(DataLogger *logger)
{
if (!logger) return -1;
// 写入文件尾
char footer[128];
switch (logger->format) {
case LOG_FORMAT_XML:
strcpy(footer, "</DataLog>\n");
WriteFile(logger->fileHandle, footer, strlen(footer));
break;
case LOG_FORMAT_JSON:
strcpy(footer, "\n ]\n}\n");
WriteFile(logger->fileHandle, footer, strlen(footer));
break;
}
// 关闭文件
int result = CloseFile(logger->fileHandle);
free(logger);
return result;
}
参考代码 利用LabWindows/CVI实现对txt文本文件的读写操作 www.youwenfan.com/contentcsu/70087.html
六、Unicode文件支持
// Unicode文件读写
int ReadUnicodeFile(const wchar_t *filename)
{
int fileHandle;
wchar_t buffer[1024];
int bytesRead;
// 以Unicode模式打开文件
fileHandle = OpenFileW(filename, VAL_READ_ONLY, VAL_OPEN_AS_IS, VAL_UNICODE);
if (fileHandle <= 0) {
// 尝试检测编码
return ReadFileWithAutoEncoding(filename);
}
// 读取Unicode文本
while ((bytesRead = ReadLineW(fileHandle, buffer, sizeof(buffer)/2)) > 0) {
buffer[bytesRead/2] = L'\0'; // 宽字符结束
// 转换为ANSI显示
char ansiBuffer[1024];
wcstombs(ansiBuffer, buffer, sizeof(ansiBuffer));
printf("%s\n", ansiBuffer);
}
CloseFile(fileHandle);
return 0;
}
// 自动检测编码
int ReadFileWithAutoEncoding(const char *filename)
{
FILE *fp = fopen(filename, "rb");
if (!fp) return -1;
// 读取BOM
unsigned char bom[3];
fread(bom, 1, 3, fp);
// 检测编码
if (bom[0] == 0xFF && bom[1] == 0xFE) {
printf("UTF-16LE 编码\n");
// UTF-16LE处理
}
else if (bom[0] == 0xFE && bom[1] == 0xFF) {
printf("UTF-16BE 编码\n");
// UTF-16BE处理
}
else if (bom[0] == 0xEF && bom[1] == 0xBB && bom[2] == 0xBF) {
printf("UTF-8 编码\n");
// UTF-8处理
}
else {
printf("ANSI/ASCII 编码\n");
// ANSI处理
}
fclose(fp);
return 0;
}
七、配置文件读写
// config_file.c
#include <ansi_c.h>
// 配置文件结构
typedef struct {
char section[64];
char key[64];
char value[256];
} ConfigItem;
// 读取INI配置文件
int ReadConfigFile(const char *filename, ConfigItem *items, int maxItems)
{
int fileHandle = OpenFile(filename, VAL_READ_ONLY, VAL_OPEN_AS_IS, VAL_ASCII);
if (fileHandle <= 0) return -1;
char line[256];
char currentSection[64] = "";
int itemCount = 0;
while (ReadLine(fileHandle, line, sizeof(line)) > 0 && itemCount < maxItems) {
// 移除前后空格
TrimWhiteSpace(line);
// 跳过空行和注释
if (line[0] == '\0' || line[0] == ';' || line[0] == '#') {
continue;
}
// 检查是否是节
if (line[0] == '[' && strchr(line, ']')) {
char *end = strchr(line, ']');
*end = '\0';
strcpy(currentSection, line + 1);
}
// 检查是否是键值对
else if (strchr(line, '=')) {
char *separator = strchr(line, '=');
*separator = '\0';
char *key = line;
char *value = separator + 1;
// 移除空格
TrimWhiteSpace(key);
TrimWhiteSpace(value);
// 保存配置项
if (currentSection[0]) {
strcpy(items[itemCount].section, currentSection);
} else {
strcpy(items[itemCount].section, "");
}
strcpy(items[itemCount].key, key);
strcpy(items[itemCount].value, value);
itemCount++;
}
}
CloseFile(fileHandle);
return itemCount;
}
// 写入配置
int WriteConfigFile(const char *filename, ConfigItem *items, int count)
{
int fileHandle = OpenFile(filename, VAL_WRITE_ONLY, VAL_TRUNCATE, VAL_ASCII);
if (fileHandle <= 0) return -1;
char lastSection[64] = "";
for (int i = 0; i < count; i++) {
// 如果节改变,写入节标题
if (strcmp(lastSection, items[i].section) != 0) {
if (items[i].section[0]) {
char sectionLine[128];
sprintf(sectionLine, "\n[%s]\n", items[i].section);
WriteFile(fileHandle, sectionLine, strlen(sectionLine));
strcpy(lastSection, items[i].section);
}
}
// 写入键值对
char line[512];
sprintf(line, "%s = %s\n", items[i].key, items[i].value);
WriteFile(fileHandle, line, strlen(line));
}
CloseFile(fileHandle);
return 0;
}
八、错误处理和调试
// 安全的文件操作
int SafeFileOperation(const char *filename, const char *mode)
{
int fileHandle = 0;
__try {
// 尝试打开文件
if (strstr(mode, "r")) {
fileHandle = OpenFile(filename, VAL_READ_ONLY, VAL_OPEN_AS_IS, VAL_ASCII);
} else if (strstr(mode, "w")) {
fileHandle = OpenFile(filename, VAL_WRITE_ONLY, VAL_TRUNCATE, VAL_ASCII);
} else if (strstr(mode, "a")) {
fileHandle = OpenFile(filename, VAL_WRITE_ONLY, VAL_APPEND, VAL_ASCII);
}
if (fileHandle <= 0) {
char errorMsg[256];
GetErrorString(errno, errorMsg, sizeof(errorMsg));
MessagePopup("文件错误", "无法打开文件 %s\n错误: %s",
filename, errorMsg);
return -1;
}
// 文件操作...
return fileHandle;
} __except(EXCEPTION_EXECUTE_HANDLER) {
MessagePopup("异常", "文件操作发生异常");
if (fileHandle > 0) {
CloseFile(fileHandle);
}
return -1;
}
}
九、主程序示例
// main.c
#include <cvirte.h>
#include <userint.h>
#include "data_logger.h"
#include "csv_handler.h"
int main(int argc, char *argv[])
{
if (InitCVIRTE(0, argv, 0) == 0) {
return -1;
}
// 示例1: 基本文件操作
WriteTextFile_Basic();
ReadTextFile_Basic("data.txt");
// 示例2: CSV文件操作
CSVFile *csv = CSV_Create("data.csv", ',');
if (csv) {
const char *headers[] = {"Time", "Sensor1", "Sensor2", "Status"};
CSV_AddHeaders(csv, headers, 4);
for (int i = 0; i < 10; i++) {
CSV_WriteRow(csv, GetCurrentDateTimeString(), 25.6 + i, 30.2 + i, "OK");
}
CSV_Close(csv);
}
// 解析CSV文件
ParseCSVFile("data.csv");
// 示例3: 数据记录器
DataLogger *logger = Logger_Create("test_log", LOG_FORMAT_CSV);
if (logger) {
double sensorData[5] = {25.6, 30.2, 12.5, 45.3, 18.7};
for (int i = 0; i < 100; i++) {
// 模拟数据变化
for (int j = 0; j < 5; j++) {
sensorData[j] += (rand() % 100) / 100.0 - 0.5;
}
Logger_WriteData(logger, sensorData, 5, "SENSOR_GROUP");
Delay(0.1); // 100ms
}
Logger_Close(logger);
}
// 示例4: 配置文件
ConfigItem config[10];
int count = ReadConfigFile("config.ini", config, 10);
if (count > 0) {
printf("读取到 %d 个配置项\n", count);
// 修改配置
for (int i = 0; i < count; i++) {
if (strcmp(config[i].key, "SamplingRate") == 0) {
strcpy(config[i].value, "1000");
}
}
WriteConfigFile("config_new.ini", config, count);
}
return 0;
}