LabWindowsCVI 文本文件读写指南

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;
}

 

专注于matlab/simulink,电子电路,编程