Все ли значения в одной строке, например, «0,100 0,840 0,030 ...», или у вас есть несколько отдельных строк, например «0,100», «0,840», «0,030» и т. Д.? Если они находятся в одной строке, разделены ли они пробелами (табуляцией, пробелами, символами новой строки) или печатными символами (запятая, точка с запятой)? Знаете ли вы, сколько значений у вас есть заранее (то есть, насколько большим должен быть ваш массив float)?
Чтобы преобразовать строку, представляющую одно значение с плавающей запятой, в double, используйте strtod()
следующим образом:
char valueText[] = "123.45";
char *unconverted;
double value;
value = strtod(valueText, &unconverted);
if (!isspace(*unconverted) && *unconverted!= 0)
{
/**
* Input string contains a character that's not valid
* in a floating point constant
*/
}
Подробнее см. strtod()
. unconverted
будет указывать на первый символ в строке, который не был преобразован strtod()
; если это не пробел или 0, то ваша строка неправильно отформатирована для значения с плавающей запятой и должна быть отклонена.
Если все значения находятся в одной строке, вам придется разбить строку на отдельные токены. Самый простой (хотя и небезопасный) способ сделать это - использовать strtok()
:
char input[] = "1.2 2.3 3.4 4.5 5.6 6.7 7.8";
char *delim = " "; // input separated by spaces
char *token = NULL;
for (token = strtok(input, delim); token != NULL; token = strtok(NULL, delim))
{
char *unconverted;
double value = strtod(token, &unconverted);
if (!isspace(*unconverted) && *unconverted != 0)
{
/**
* Input string contains a character that's not valid
* in a floating point constant
*/
}
}
Подробнее см. На strtok()
.
Если вы не знаете, сколько значений у вас заранее, вам нужно будет немного поработать с памятью. Вы можете динамически выделить массив с плавающей точкой некоторого начального размера, используя malloc()
или realloc()
, а затем периодически расширять его, используя realloc()
:
#define INITIAL_EXTENT 10
double *array = NULL;
size_t arraySize = 0;
size_t arrayIdx = 0;
char input[] = ...; // some long input string
char *delim = ...; // whatever the delimiter set is
char *token;
/**
* Create the float array at some initial size
*/
array = malloc(sizeof *array * INITIAL_EXTENT));
if (array)
{
arraySize = INITIAL_EXTENT;
}
/**
* Loop through your input string
*/
for (token = strtok(input, delim); token != NULL; token = strtok(NULL, delim))
{
double val;
char *unconverted;
if (arrayIdx == arraySize)
{
/**
* We've reached the end of the array, so we need to extend it.
* A popular approach is to double the array size instead of
* using a fixed extent; that way we minimize the number
* of calls to realloc(), which is relatively expensive.
*
* Use a temporary variable to receive the result; that way,
* if the realloc operation fails, we don't lose our
* original pointer.
*/
double *tmp = realloc(array, sizeof *array * (arraySize * 2));
if (tmp != NULL)
{
array = tmp;
arraySize *= 2;
}
else
{
/**
* Memory allocation failed; for this example, we just exit the loop
*/
fprintf(stderr, "Memory allocation failed; exiting loop\n");
break;
}
}
/**
* Convert the next token to a float value
*/
val = strtod(token, &unconverted);
if (!isspace(*unconverted) && *unconverted != 0)
{
/**
* Bad input string. Again, we just bail.
*/
fprintf(stderr, "\"%s\" is not a valid floating-point number\n", token);
break;
}
else
{
array[arrayIdx++] = val;
}
}
Не забудьте free()
массив, когда вы закончите с ним.