假设您有一个变量char s[30]
,并且s
以正浮点数开头,例如
s = "15.016This is not a part of the float !";
浮动之后的角色可能只是一个数字。
目标是确定浮点数表示的字符数,例如| 15.016 | = 6.
我正在尝试编写一个简单的代码,最好没有任何外部库。
我有:
int count_len(char *s)
{
char tmp_buf[30];
int integral_digits = sprintf(tmp_buf, "%d", atoi(s) );
return integral_digits + sprintf(tmp_buf, "%d", atoi(s + integral_digits +1) );
}
这适用于分数不包含前导零的任何数字(适用于15.16,但不适用于15.016)。
你将如何修复这个功能?
答案 0 :(得分:4)
为什么不简单地将sscanf
与adhoc格式说明符一起使用?
考虑
sscanf("15.01336This is not a part of the float !", "%*f%n", &len);
%*f%n
表示
%*f
读取一个的浮动数字,但不要将其存储在任何地方,只需使用它。%n
存储了消费字符数。一个工作示例
#include <stdio.h>
int main()
{
int len;
sscanf("15.01336This is not a part of the float !", "%*f%n", &len);
printf("%d\n", len);
return 0;
}
答案 1 :(得分:2)
C是黑客攻击,所以为什么不动态编写你的函数,例如:
size_t floatlenghth(char *s)
{
size_t len = 0;
short found_dot = FALSE;
while ((*s >= '0' && *s <= '9') || (*s == '.' && !found_dot)) {
len += 1;
if (*s == '.') found_dot = TRUE;
s++;
}
return len;
}
让事情变得复杂,
您必须查看区域设置(如','表示小数分隔符)。
.... char dottype = getdottypeforlocale();
.... if(* s == dottype)
你想如何计算一个点后的前导零和尾随零(f.e。“001.200blubber”是长度为7还是长度为3?)
... s = skipleadingzeros(s);
在 / if(found_dot&amp;&amp; * s =='0')counttrailingzeros ++中,... / 在里面别counttrailingzeros = 0;
在 / len - = counttrailingzeros; ... /
科学记数法:1.22E01 ...在while()之后看看iff * s ='E'并且接下来的两个字符是数字,然后加3 thousender-mark(s),如1'234.56(这在哪里有效?)或1,234.56(英文)或1.234,56(德文)或1,234,567.89
答案 2 :(得分:1)
如果你有一个模式的输入字符串,
"15.016This is not a part of the float !";
正如您在问题中提到的,我建议您使用string.h
中提供的strspn()
或strcspn()
功能来查找长度float类型的>。
如果您使用strspn()
,则可以将accept
设置为所有数字并点.
。
您不需要外部库来使用它们。它们是标准C
和glibc
的一部分。
答案 3 :(得分:1)
int count_len(char *s){
int len = 0;
sscanf(s, "%*lf%n", &len);
return len;
}
答案 4 :(得分:1)
strtod
非常适合:
char *endOfFloat;
double val = strtod( str, &endOfFloat );
size_t len = (size_t) endOfFloat - str;
这假设字符串的float部分格式正确,可表示为double
。
如果情况并非如此,那么您需要采用不同的方法。
答案 5 :(得分:0)
我在3分钟内写完了这篇文章。它有几个错误,例如,它在数字的右侧计为零。这是你可以自己解决的问题:)
int count_len(const char *s)
{
const int sz = strlen(s);
int sz_of_float = 0;
bool dot = false; // to avoid double dots like ".."
for(int i = 0; i < sz; i++)
{
if(s[i] >= '0' && s[i] <= '9')
sz_of_float++;
else if(s[i] == '.' && dot == false)
{
dot = true;
sz_of_float++;
}
else
return sz_of_float;
}
return -1;
}
答案 6 :(得分:0)
以下是如何考虑编写此类函数的算法。
示例代码:
int countDigits(char const * str)
{
int count = 0;
int i;
if (str == NULL) return 0;
for (i = 0; str[i] != '\0'; i++) {
if (isdigit(str[i]))
count++;
else
break;
}
}
int countFloatChars(char const * str)
{
int count = 0;
if (str == NULL) return 0;
if (str[0] == '\0') return 0;
if ((str[0] < '1') || (str[0] > '9')) return 0;
count = 1;
count += countDigits(str + count);
if ((str[count] == '\0') || (str[count] != '.')) return count;
count++;
count += countDigits(str + count);
return count;
}
答案 7 :(得分:0)
不使用C库,寻找至少找到1位数的(digits).(digits)
:
size_t float_length(const char *s) {
const char *p = s;
int digit_count = 0;
// could add tests for white-space, +, - here
while (*p >= '0' && *p <= '9') {
s++;
digit_found = 1;
}
if (*p == '.') {
p++;
while (*p >= '0' && *p <= '9') {
p++;
digit_found = 1;
}
}
if (digit_found) return (size_t) (p - s);
return 0;
}
没什么特别的。