计算给定字符串的浮点数的长度
Count the length of a float given string
假设您有一个变量 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)。
你会如何修复这个函数?
如果你有模式的输入字符串,
"15.016This is not a part of the float !";
正如您在问题中提到的,我建议您使用 string.h
中可用的函数 strspn()
or strcspn()
来找出 长度 领先的 float
类型。
如果使用strspn()
,可以将accept
设置为所有数字和点.
。
您不需要外部 库即可使用它们。它们是标准 C
和 glibc
.
的一部分
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);
... /里面 while/ if (found_dot && *s == '0') counttrailingzeros++;否则 counttrailingzeros = 0;
... /while/ 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
int count_len(char *s){
int len = 0;
sscanf(s, "%*lf%n", &len);
return len;
}
我在 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;
}
为什么不简单地使用带有临时格式说明符的 sscanf
?
考虑
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。否则,退出并 return 为零。
- 从下一个字符开始,在遇到非数字字符或字符串末尾之前读入最大位数,每次递增计数。
- 如果到达字符串末尾,则退出并return 计数。否则,如果字符是句号,则计数加 1。
- 从句点后的下一个字符开始,在遇到非数字字符或字符串结尾之前读入最大位数,每次递增计数。
- Return 计数。
示例代码:
int countDigits(char const * str)
{
int count = 0;
int i;
if (str == NULL) return 0;
for (i = 0; str[i] != '[=10=]'; i++) {
if (isdigit(str[i]))
count++;
else
break;
}
}
int countFloatChars(char const * str)
{
int count = 0;
if (str == NULL) return 0;
if (str[0] == '[=10=]') return 0;
if ((str[0] < '1') || (str[0] > '9')) return 0;
count = 1;
count += countDigits(str + count);
if ((str[count] == '[=10=]') || (str[count] != '.')) return count;
count++;
count += countDigits(str + count);
return count;
}
strtod
非常适合这个:
char *endOfFloat;
double val = strtod( str, &endOfFloat );
size_t len = (size_t) endOfFloat - str;
这假设字符串的浮点部分格式正确并且可以表示为 double
。
如果不是这种情况,您将需要不同的方法。
不使用 C 库,查找 (digits).(digits)
其中至少找到 1 个数字:
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;
}
没什么好看的。
假设您有一个变量 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)。
你会如何修复这个函数?
如果你有模式的输入字符串,
"15.016This is not a part of the float !";
正如您在问题中提到的,我建议您使用 string.h
中可用的函数 strspn()
or strcspn()
来找出 长度 领先的 float
类型。
如果使用strspn()
,可以将accept
设置为所有数字和点.
。
您不需要外部 库即可使用它们。它们是标准 C
和 glibc
.
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);
... /里面 while/ if (found_dot && *s == '0') counttrailingzeros++;否则 counttrailingzeros = 0;
... /while/ 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
int count_len(char *s){
int len = 0;
sscanf(s, "%*lf%n", &len);
return len;
}
我在 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;
}
为什么不简单地使用带有临时格式说明符的 sscanf
?
考虑
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。否则,退出并 return 为零。
- 从下一个字符开始,在遇到非数字字符或字符串末尾之前读入最大位数,每次递增计数。
- 如果到达字符串末尾,则退出并return 计数。否则,如果字符是句号,则计数加 1。
- 从句点后的下一个字符开始,在遇到非数字字符或字符串结尾之前读入最大位数,每次递增计数。
- Return 计数。
示例代码:
int countDigits(char const * str)
{
int count = 0;
int i;
if (str == NULL) return 0;
for (i = 0; str[i] != '[=10=]'; i++) {
if (isdigit(str[i]))
count++;
else
break;
}
}
int countFloatChars(char const * str)
{
int count = 0;
if (str == NULL) return 0;
if (str[0] == '[=10=]') return 0;
if ((str[0] < '1') || (str[0] > '9')) return 0;
count = 1;
count += countDigits(str + count);
if ((str[count] == '[=10=]') || (str[count] != '.')) return count;
count++;
count += countDigits(str + count);
return count;
}
strtod
非常适合这个:
char *endOfFloat;
double val = strtod( str, &endOfFloat );
size_t len = (size_t) endOfFloat - str;
这假设字符串的浮点部分格式正确并且可以表示为 double
。
如果不是这种情况,您将需要不同的方法。
不使用 C 库,查找 (digits).(digits)
其中至少找到 1 个数字:
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;
}
没什么好看的。