C将字符数组的部分转换为双精度

C将字符数组的部分转换为双精度,c,pointers,casting,char,atof,C,Pointers,Casting,Char,Atof,我想将char数组的一部分转换为double。例如,我有: char in_string[] = "4014.84954"; 假设我要将第一个40转换为值为40.0的双精度。到目前为止,我的代码是: #include <stdio.h> #include <stdlib.h> int main(int arg) { char in_string[] = "4014.84954"; int i = 0; for(i = 0; i <= sizeof(

我想将char数组的一部分转换为double。例如,我有:

char in_string[] = "4014.84954";
假设我要将第一个
40
转换为值为
40.0
的双精度。到目前为止,我的代码是:

#include <stdio.h>
#include <stdlib.h> 

int main(int arg) {
  char in_string[] = "4014.84954";
  int i = 0;
  for(i = 0; i <= sizeof(in_string); i++) {
    printf("%c\n", in_string[i]);
    printf("%f\n", atof(&in_string[i]));
  }
}

如何将字符数组的一部分转换为双精度?这必须是模块化的,因为我的实际输入字符串要复杂得多,但我将确保字符是数字0-9。

您可以将所需数量的字符串复制到另一个
字符
数组,以null终止它,然后将其转换为双精度。例如,如果需要2个数字,请将所需的2个数字复制到长度为3的
char
数组中,确保第3个字符是空终止符


或者,如果不想创建另一个
字符
数组,可以备份字符数组的第(n+1)个字符,将其替换为空终止符(即0x00),调用
atof
,然后用备份的值替换空终止符。这将使
atof
停止解析您放置空终止符的位置。

您可以将所需数量的字符串复制到另一个
char
数组,空终止它,然后将其转换为双精度字符串。例如,如果需要2个数字,请将所需的2个数字复制到长度为3的
char
数组中,确保第3个字符是空终止符


或者,如果不想创建另一个
字符
数组,可以备份字符数组的第(n+1)个字符,将其替换为空终止符(即0x00),调用
atof
,然后用备份的值替换空终止符。这将使
atof
在放置空终止符的位置停止解析。

假设以下情况可行:

我将确保字符是数字0-9

例如,对于字符串
23487
,函数将执行以下计算:

ret = 0
ret += 7 * 1
ret += 8 * 10
ret += 4 * 100
ret += 3 * 1000
ret += 2 * 10000
ret = 23487

假设以下各项可行:

我将确保字符是数字0-9

例如,对于字符串
23487
,函数将执行以下计算:

ret = 0
ret += 7 * 1
ret += 8 * 10
ret += 4 * 100
ret += 3 * 1000
ret += 2 * 10000
ret = 23487

那么,在正确的位置插入
NULL
,然后将其恢复为原始字母?这意味着您将操作字符数组,但最后会将其还原为原始字母。

如何,在正确的位置插入
NULL
,然后将其还原为原始字母?这意味着您将操作char数组,但最后会将其还原为原始数组。

您可以创建一个函数,使其在临时字符串(堆栈上)中工作,并返回结果双精度:

double atofn (char *src, int n) {
  char tmp[50]; // big enough to fit any double

  strncpy (tmp, src, n);
  tmp[n] = 0;
  return atof(tmp);
}

您可以创建一个函数,使工作成为临时字符串(在堆栈上),并返回结果双精度:

double atofn (char *src, int n) {
  char tmp[50]; // big enough to fit any double

  strncpy (tmp, src, n);
  tmp[n] = 0;
  return atof(tmp);
}

就用吧。使用格式“ld”并检查返回值是否为1。

只需使用即可。使用格式“ld”并检查返回值是否为1。

它比1简单多少

#包括
#包括
内部主(空){
双福;
断言(sscanf(“4014.84954”、“%02lf”、&foo)==1);
printf(“处理了输入的前两个字节并得到:%lf\n”,foo);
断言(sscanf(“4014.84954”+2、%05lf”、&foo)==1);
printf(“处理了接下来的五个字节的输入并获得了:%lf\n”,foo);
断言(sscanf(“4014.84954”+7、%lf”、&foo)==1);
printf(“已处理其余输入并获得:%lf\n”,foo);
返回0;
}

它能比

#包括
#包括
内部主(空){
双福;
断言(sscanf(“4014.84954”、“%02lf”、&foo)==1);
printf(“处理了输入的前两个字节并得到:%lf\n”,foo);
断言(sscanf(“4014.84954”+2、%05lf”、&foo)==1);
printf(“处理了接下来的五个字节的输入并获得了:%lf\n”,foo);
断言(sscanf(“4014.84954”+7、%lf”、&foo)==1);
printf(“已处理其余输入并获得:%lf\n”,foo);
返回0;
}

最好尽量避免
pow
,因为它太慢了。@GraphicsMancher说,谁?这种方法的真正问题是容易出现舍入错误(因为
pow()
以及底层格式是二进制而不是十进制),因此使用有限。@AlexeyFrunze,OP确保字符串中没有
符号,因此不需要小数。这可能是最快的正确方法,因为它是为OP需求而构建的(用途有限)。我也没有看到任何回旋处。你能指出它们吗?@Jueecy
pow()
可能返回10的不精确整数幂。直接乘以101001000等更可靠。如果可能的话,最好避免
pow
,因为它太慢了。@graphicsmancher,who说?这种方法的真正问题是容易出现舍入错误(因为
pow()
以及底层格式是二进制而不是十进制)因此它的用途有限。@AlexeyFrunze,OP确保字符串中没有
符号,因此不需要小数。这可能是最快的正确方法,因为它是为OP需求而构建的(用途有限)。我也没有看到任何回旋处。你能指出它们吗?@Jueecy
pow()
可能返回10的不精确整数幂。直接乘以101001000会更可靠,“是”,而不是“ld”?否。“lf”不是“ld”。“ld”对应于
long int
。“lf”对应于
double
@modifiablelvalue-问题是d在我键盘上的f旁边。还有,为什么我的狗要求在早上5点散步,尽管我们刚刚退休,“是”而不是“ld”?否。“lf”不是“ld”。“ld”对应于
long int
。“lf”对应于
double
@modifiablelvalue-问题是d在我键盘上的f旁边。还有,为什么我的狗要求在早上5点散步,尽管我们刚刚退休?
#include <assert.h>
#include <stdio.h>

int main(void) {
    double foo;
    assert(sscanf("4014.84954", "%02lf", &foo) == 1);
    printf("Processed the first two bytes of input and got: %lf\n", foo);

    assert(sscanf("4014.84954" + 2, "%05lf", &foo) == 1);
    printf("Processed the next five bytes of input and got: %lf\n", foo);

    assert(sscanf("4014.84954" + 7, "%lf", &foo) == 1);
    printf("Processed the rest of the input and got: %lf\n", foo);
    return 0;
}