字符串长度有限的字符串

如果我想将char数组中的前3个字符解析为double,忽略以下字符,我真的需要这样做吗?

 int main(){
     const char a [] =“1.23”;
     char * b = malloc(sizeof(char)* 4);

     memcpy(b,a,sizeof(char)* 3);
     b [3] ='\ 0';

     printf(“%f \ n”,strtod(b,NULL));  //打印1.20000,这就是我想要的

    自由(B);
 }

是不是像strtod这样的函数允许你指定它应该搜索数字的最大字符串长度?

编辑:我希望它打印1.2 (它目前做), 而不是 1.23

如果您始终只想考虑给定字符串中的三个第一个字符,则可以使用以下代码:

 #include  #include  double parse_double(const char *str) { char *tmp = 0; double result = 0; asprintf(&tmp, "%.3s", str); result = strtod(tmp, 0); free(tmp); return result; } int main(void) { printf("%f\n", parse_double("1.23")); // 1.2 printf("%f\n", parse_double("1234")); // 123 printf("%f\n", parse_double("0.09")); // 0.0 return 0; } 

虽然strtod()不允许您限制字符串长度,但您可以使用具有最大字段宽度的 sscanf()并可选地检查所消耗的字符数,如下所示:

 #include  double parseDouble(const char *str){ double val = 0; int numCharsRead; // Handle errors by setting or returning an error flag. if(sscanf(str, "%3lf%n", &val, &numCharsRead) != 1){ puts("Failed to parse double!"); } else if(numCharsRead != 3){ puts("Read less than three characters!"); } return val; } int main(){ printf("%lf\n", parseDouble("1.3")); // 1.300000 printf("%lf\n", parseDouble("1.5999")); // 1.500000 printf("%lf\n", parseDouble(".391")); // 0.390000 printf("%lf\n", parseDouble(".3")); // Read less than three characters!\n0.300000 return 0; } 

sscanf(str, "%3lf%n", &val, &numCharsRead是重要的部分:指定最大宽度为3,这意味着sscanf()将为该特定字段读取最多3个字符,并且还存储数量numCharsRead解析结束时消耗的字符。如果你每次只读3个字符就可以检查该值;如果3或更少,你就可以使用sscanf(str, "%3lf", &val) 。作为参考,这里是宽度说明符的文档:

可选的十进制整数,指定最大字段宽度。 当达到此最大值或找到不匹配的字符时(无论哪个先发生),读取字符都会停止。 大多数转换会丢弃最初的空格字符(下面会提到例外情况),这些丢弃的字符不会计入最大字段宽度。 字符串输入转换存储一个终止空字节(’\ 0’)以标记输入的结尾; 最大字段宽度不包括此终止符。

strtod的签名是这样的

  double strtod(const char *nptr, char **endptr); 

该函数将返回nptr的字符串的初始部分。 如果endptr不为NULL ,则指向转换中使用的最后一个字符后的字符的指针将存储在endptr引用的位置。

因此,它不允许您指定需要转换的字符数。 因此,您必须自己修改输入并将其传递给strtod

不,标准库中没有这样的function。

但是推出一个人自己很有趣:

 /* * Same as strtod() but only takes the first n characters into account. * Additionally returns 0. and sets errno to EINVAL if 'nptr' is NULL. */ double strntod(const char *nptr, char **endptr, size_t n) { double result; /* perform input validation */ if (!nptr) { errno = EINVAL; result = 0.; if (endptr) { *endptr = nptr; } goto lblExit; } if (strlen(nptr) <= n) { /* Nothing to truncate: fall back to standard 'strtod()' */ result = strtod(nptr, endptr); } else { /* create working copy of string */ char * ptmp = strdup(nptr); /* Test whether 'strdup()' failed */ if (!ptmp) { result = 0.; if (endptr) { *endptr = nptr; } goto lblExit; } /* truncate working copy to n characters */ ptmp[n] = `\0`; /* do original 'strtod()' on truncated working copy */ result = strtod(ptmp, endptr); /* adjust '*endptr' to point to original character array, but to working copy */ if (endptr) { *endptr = nptr + (*endptr - ptmp); } /* free working copy */ free(ptmp); } lblExit: return result; }