我正在从SD卡读取STM32嵌入式应用程序的数据.该数据被写入文本文件中.

char resultFormat[100] = "%s\n%s\n%s\n%lf\n%lf\n%lf\n%i\n%i\n%i\n";

void readResult(int indexNumber)
{
    FRESULT fr;
    FIL MyFile;     /* File object */
    size_t read;
    UINT bytesRead;

    FATFS SDFatFs;  /* File system object for SD disk logical drive */

    fr =  f_mount(&SDFatFs, (TCHAR const *)SDPath, 0); //Mounts the file

    char fileName[20];
    char directory[10] = "RESULTS";
    sprintf(fileName, "%s/%i.TXT", directory, indexNumber);

    fr = f_open(&MyFile, fileName, FA_READ); //Opens the file
    read = f_read(&MyFile, resultBuffer, sizeof resultBuffer, &bytesRead);  //Writes the txt from the txt file to a string.

    vTaskDelay(200);
    f_close(&MyFile); //Closes the file

    sscanf(resultBuffer, resultFormat, resultDate, resultTime, presetName,
           &correctedFlash, &observedFlash, &pressure, &flashedStatus,
           &resultStartTemp, &status);

    sendResultInfo(); //Processes the variables. Not relevant.

    fr = f_mount(NULL, "", 0); //Unmounts the file.
}

我的主要问题是:

char resultFormat[100] = "%s\n%s\n%s\n%lf\n%lf\n%lf\n%i\n%i\n%i\n";
sscanf(resultBuffer, resultFormat, resultDate, resultTime, presetName,
       &correctedFlash, &observedFlash, &pressure, &flashedStatus,
       &resultStartTemp, &status);

我有相当多的变量需要从字符串中读取,如果我更改了任何内容,我还必须更改resultFormat,这可能会导致错误.

现在,变量的数量是可管理的,但我想知道如果我有更多的数据要从文本文件中读取,比如我有here个不同类型的变量要读取,应该如何读取这些数据.sscanf似乎太容易出现人为错误,无法在这种情况下可靠地使用,我想知道是否有从字符串读取数据的替代方法.前面的问题here提供了一个解决sscanf长阅读的方案,但我想知道是否还有其他的解决方案.


我的第二个问题(不确定是否适合这个堆栈,但我的印象是它会被提出来)是在不使用文本文件的情况下存储这些数据,而不是将其存储为字符串.

我拥有的数据中没有多少是字符串,其中一些是整型和双精度型,但存储为字符串.

虽然我目前的系统工作正常(而且很适合调试,因为我可以很容易地从外部读取存储的数据),但我想知道应该如何格式化非字符串数据并将其存储在SD卡中.

如果需要更多的信息或详细说明,请让我知道.

推荐答案

  1. scanf格式中,几乎从不需要\n.如果go 掉它们,你将得到一个更容易阅读的字符串.
  2. Never使用不是字符串文字的格式字符串调用scanf和朋友.编译器编写者在捕获格式错误方面投入了大量工作,但通过使实际的格式字符串在调用位置不可见,您正在将其全部丢弃.
  3. 考虑使用字符串文字连接来将变量与其格式对齐.

像这样的电话

sscanf(resultBuffer,
       "%s"        "%s"        "%s"        "%lf"            "%lf"           "%lf"      "%i"            "%i"              "%i",
       resultDate, resultTime, presetName, &correctedFlash, &observedFlash, &pressure, &flashedStatus, &resultStartTemp, &status);

almost是可维护的.如果您弄乱了格式字符串,使其不再与实际参数相对应,您将收到编译器警告.只需看一眼,就可以知道格式的哪个部分对应于哪个变量.它唯一的问题是它太长了,你不能把它分成几行而不会失go 视觉对齐.如果您遇到此问题,请将缓冲区调用拆分为几个较小的调用,或者完全远离scanf.

C++相关问答推荐

C中空终止符后面的数字?

ISO_C_BINDING,从Fortran调用C

如果实际的syscall是CLONE(),那么为什么strace接受fork()呢?

为什么我得到更多的256假阳性在PKZIP解密密钥验证?

需要大整数和浮点数.使用long long int和long double

如何使用Python C API实现多线程程序?

#If指令中未定义宏?

在C++中头文件中声明外部 struct

如何使用C for Linux和Windows的标准输入与gdb/mi进行通信?

插座打开MacOS组件

将返回的char*设置为S在函数中定义的字符串文字可能会产生什么问题?

C程序向服务器发送TCPRST

从C中的函数返回静态字符串是不是一种糟糕的做法?

为什么会导致分段故障?(C语言中的一个程序,统计文件中某个单词的出现次数)

C中的空指针是什么(_N)?

可以';t从A9G模块拨打电话

Tcl_GetDoubleFromObj在列表的迭代中是一个缺点

如何使用 VLA 语法使用 const 指针声明函数

与 C 相比,C++ 中无副作用的无限循环的好处是 UB?

返回指向函数内声明的复合文字的指针是否安全,还是应该使用 malloc?