В дополнении к решениям, предусмотренным в других ответах, когда сталкиваются с грязной линией ввода для чтения, может быть проще использовать линию ориентированных на входных функции, предусмотренных libc
(например, fgets
или getline
). Считывание данных одной строки в то время в буфер, часто (не всегда) дает большую гибкость при анализе данных с другими инструментами, предоставленных libc
(например strtok
, strsep
, и т.д ..)
с другими данными, ориентированный на характер вход - лучший выбор. В вашем случае линии чередуются с многочисленными '"'
, ':'
, ' '
и ','
. Это затрудняло построение строки формата fscanf
для чтения обоих обменных курсов в одном вызове или с использованием любого инструмента синтаксического анализа строк, такого как strtok
. Так что это был действительно жесткий вызов. Я согласен, решение BluePixyes для разбора одного float
в вызове fscanf
является хорошим решением. ориентированная на линию альтернатива - читать строку за раз, а затем использовать strtof
для преобразования значений поплавка, найденных в строке. Единственное преимущество, которое предоставляет strtof
, - это проверка ошибок при преобразовании, которая позволяет проверить хорошее преобразование поплавка.Это один из подходов для линии-ориентированного раствора:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <limits.h>
int main() {
FILE* file = NULL; /* aways initialize variables */
float rate[16] = {0.0}; /* market rates 1st & 2nd */
char myFile[50] = {0}; /* input filename */
char line[128] = {0}; /* input line buffer */
char *p = NULL; /* pointer to parse line */
char *ep = NULL; /* pointer to parse line */
size_t idx = 0; /* index for rate array values */
size_t it = 0; /* general index iterator */
/* prompt for filename */
printf ("\n Please enter filename to read rates from: ");
scanf ("%[^\n]%*c", myFile);
/* open & validate file */
file = fopen (myFile, "r");
if (!file) {
fprintf(stderr, "error: Unable to read the file!\n");
return 1;
}
/* using line-oriented input to read line, then parse */
while (fgets (line, 127, file) != NULL)
{
if (idx == 16) {
fprintf (stderr, "warning: array full.\n");
break;
}
p = line; /* parse line for floats */
while (*p) { /* find first digit or end */
while (*p && (*p < 48 || *p > 57)) p++;
if (!*p) break; /* validate not null */
rate[idx++] = strtof (p, &ep); /* get float, set end-ptr */
if (errno != 0 || p == ep) /* validate conversion */
fprintf (stderr, "discarding: rate[%zd] invalid read\n", --idx);
p = ep; /* set ptr to end-ptr */
}
}
fclose (file);
printf ("\n The exchange rates read from file:\n\n");
for (it = 0; it < idx; it++)
printf (" rate[%2zd] = %9.7f\n", it, rate[it]);
printf ("\n");
return 0;
}
ввода пробы:
$ cat dat/rates.txt
"USD_EUR": "0.8631364", "EUR_USD": "1.3964719"
"USD_AGT": "0.9175622", "EUR_USD": "1.0975372"
"USD_BRZ": "0.8318743", "EUR_USD": "1.1713074"
"USD_COL": "0.9573478", "EUR_USD": "1.0537964"
"USD_GIA": "0.7904234", "EUR_USD": "1.5393454"
выхода:
$ ./bin/read_xchgrates
Please enter filename to read rates from: dat/rates.txt
The exchange rates read from file:
rate[ 0] = 0.8631364
rate[ 1] = 1.3964719
rate[ 2] = 0.9175622
rate[ 3] = 1.0975372
rate[ 4] = 0.8318743
rate[ 5] = 1.1713074
rate[ 6] = 0.9573478
rate[ 7] = 1.0537964
rate[ 8] = 0.7904234
rate[ 9] = 1.5393454
Примечание: проверить strtof
для любого дополнительного #define
может потребоваться ваш компилятор.
Сколько вы понимаете C строк? Вы не можете просто 'str =" "'. – guest
и пытаетесь ли вы называть 'strcat (char *, int)'? – guest
в 'change', изменение положения [0] [0] пропускается. – user3629249