我在C中有一个字符串,我从一些算法中获得。它具有像这样的格式的数值
0.100
0.840
0.030
0.460
0.760
-0.090
等等
需要将每个这些数值存储到float数组中进行数值处理。我是C的新手,发现C中的字符串处理很复杂。任何人都可以告诉我如何实现这一点。
答案 0 :(得分:2)
使用strtod()
。与atof()
不同,它可以检测输入字符串中的错误。
#include <stdio.h>
#include <stdlib.h>
int main(void) {
char buf[] = "0.100\n0.8foo40\n0.030\n\n\n\n0.460\n0.760bar\n-0.090trash";
char *err, *p = buf;
double val;
while (*p) {
val = strtod(p, &err);
if (p == err) p++;
else if ((err == NULL) || (*err == 0)) { printf("Value: %f\n", val); break; }
else { printf("Value: %f\n", val); p = err + 1; }
}
return 0;
}
除非出现错误,否则 strtod()
将返回读取的值。
如果err
指向传入的字符串,则不能在字符串中使用任何内容,所以在上面的代码片段中,我将p递增以继续从下一个位置读取。
如果err
为NULL或指向空字符串,则没有错误,因此,在我的代码段中,我打印该值并停止循环。
如果err
指向字符串中的某个位置(不是p
本身,之前已经过测试过),那就是错误的字符,在我上面的代码段中,我知道有些东西被读了,所以我打印它,将p设置为错误并循环。
编辑为了完整起见,我应该提一下错误的情况。可能会发生strtod()
读取一个字符序列(尽管有效)不能由double
表示。在这种情况下,errno
设置为ERANGE,值本身“无意义”。在使用返回的值之前,您应该在调用errno
之前将strtod()
设置为0并在之后进行检查。对于极小的输入值(例如“1E-42000”),设置errno
是实现定义的,但返回0(或几乎为0)。
答案 1 :(得分:1)
是否所有值都在一个字符串中,例如“0.100 0.840 0.030 ...”,或者您是否有一堆单独的字符串,如“0.100”,“0.840”,“0.030”等?如果它们是单个字符串,它们是用空格(制表符,空格,换行符)还是用打印字符(逗号,分号)分隔的?你知道你提前有多少值(即你的浮点数需要多大)?
要将表示单个浮点值的字符串转换为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()
动态分配一些初始大小的float数组,然后使用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()
数组。
答案 2 :(得分:0)
答案 3 :(得分:0)
您想要的功能称为fscanf。
/* fscanf example */
/* Stolen from cplusplus.com
Modified by C Ross */
#include <stdio.h>
int main ()
{
char str [80];
float f;
FILE * pFile;
pFile = fopen ("myfile.txt","r");
/* Loop over this and add to an array, linked list, whatever */
fscanf (pFile, "%f", &f);
fclose (pFile);
printf ("I have read: %f \n",f);
return 0;
}
答案 4 :(得分:0)
假设你的字符串是
char *str;
使用类似的东西:
double d[<enter array size here>];
double *pd = d;
for(char *p = str; p = strchr(p, '\n'); p++, pd++)
{
*p = 0;
*pd = atof(p);
*p = '\n';
}
答案 5 :(得分:0)
如果它是一个字符串,首先需要将它拆分为新行字符(s?)然后你可以使用“atof”stdlib函数从它们创建浮点数。像这样的东西: