Есть ли простой способ разобрать число с плавающей запятой в C ++ GNU ARM встроен? - PullRequest
1 голос
/ 05 июня 2019

У меня есть эта строка во встроенной системе C ++ GNU ARM:

char* TempStr = "pressure 0.85";

Мне нужно, чтобы числовое значение хранилось как отдельная переменная с плавающей точкой, называемая presmax

До сих пор анализируемое число всегда было целым числом, поэтому я мог без проблем использовать sscanf. Однако, как я много читал в Интернете (и из первых рук), sscanf обычно не работает с плавающими объектами во встроенных системах (без какой-либо обширной конфигурации / потери места на флэш-памяти).

Мне интересно, есть ли у кого-нибудь предложения. Возможно, я мог бы разобрать "0.85" как массив символов? Я не совсем уверен, как это сделать, хотя это позволило бы мне использовать atof (), чтобы превратить его в float, как я делал в других местах программы.

Я понимаю, что другой вариант - написать функцию, однако я довольно программист-любитель, поэтому, если есть более надежное и эффективное по времени решение, я бы лучше его взял.

UPDATE: В случае, если это помогает, TempStr - это строка, скопированная из файла .txt на SD-карту с использованием FatFs. Вот полный код, который читает две строки и каждый раз сохраняет результаты в TempStr. Я анализирую строку в соответствующей переменной каждый раз, когда сохраняется TempStr:

FILINFO fno;
FIL fsrc;
int FileEnd = 0;
int CurrentLine = 0;
int pressmax = 0;
int timemax = 0;
char* TempStr;
WCHAR CharBuffer[100];

res = f_stat("config.txt", &fno);                               //check for config.txt file
res = f_open(&fsrc, "config.txt", FA_READ | FA_OPEN_ALWAYS);    //open config.txt file

//first line
TempStr = f_gets((char*)CharBuffer, sizeof(fsrc), &fsrc);      
CurrentLine ++;
FileEnd = FileEnd + strlen(TempStr) + 1;

//sscanf(TempStr, "%*s %i", &presmax);       //what I did when presmax was an int

//second line
while ((f_eof(&fsrc) == 0)){                                   
        TempStr = f_gets((char*)CharBuffer, sizeof(fsrc), &fsrc);
        CurrentLine ++;
        FileEnd = FileEnd + strlen(TempStr) + 1;
}

//sscanf(TempStr, "%*s %i", &timemax);     

Использование инструментов сборки GNU ARM на STM32L с Eclipse.

Ответы [ 2 ]

0 голосов
/ 05 июня 2019

Это можно сделать следующим образом:

float presmax = (float)atof( strchr( TempStr, ' ' ) ;

Приведение необходимо только потому, что ваш вопрос специально запрашивает float, а atof() возвращает double. В любом случае приведение будет неявным, поэтому:

float presmax = atof( strchr( TempStr, ' ' ) ;

также приемлемо.

strchr() возвращает указатель на первый пробел, а atof() игнорирует любой начальный пробел. Если ваш конфигурационный файл может использовать символ табуляции, то:

float presmax = (float)atof( strpbrk( TempStr, " \t" ) ;

Сбой, если либо strchr(), либо strpbrk() вернет NULL, когда разделитель не найден, поэтому вы можете сделать его более устойчивым, таким образом:

#define PRESMAX_DEFAULT 1.0f

const char* prestr = strchr( TempStr ) ;
float presmax = prestr == NULL ? PRESMAX_DEFAULT : (float)atof( prestr ) ;
0 голосов
/ 05 июня 2019

Если вам гарантировано, что ваш ввод будет в форме

text floating_point_number

, то, получив TempStr, вы можете перемещать указатель по нему до тех пор, пока не достигнете пробела, а затем перейти на одну позициюДалее, чтобы добраться до плавающей запятой части строки.Затем вы передаете этот указатель на atof, чтобы получить значение из оставшейся части строки.Это выглядело бы как

char* fp = TempStr;
while (*fp != ' ') ++fp; // get to the space
double value = atof(++fp); // advance to floating point part and pass to atof

Если вам не нужно TempStr после получения значения, вы можете избавиться от fp и просто использовать

while (*TempStr != ' ') ++TempStr ; // get to the space
double value = atof(++TempStr); // advance to floating point part and pass to atof
...