我只想计算文本文件中包含数字的字符串数。但是下面的代码甚至将文件中的数字计为字符串。我该如何纠正这个问题?
int count;
char *temp;
FILE *fp;
fp = fopen("multiplexyz.txt" ,"r" );
while(fscanf(fp,"%s",temp) != EOF )
{
count++;
}
printf("%d ",count);
return 0;
}
答案 0 :(得分:1)
好吧,首先,使用temp
指针而没有后备存储,这将会让你感到痛苦。
我建议首先使用类似char temp[1000]
之类的内容,但请注意,如果您的字数超过一千个字符,那么它仍然有点风险(&& #39;与您提出的问题存在不同的问题,因此我会提及它,但不会花太多时间修复它。< / p>
其次,您似乎想要计算带有数字的字词(例如alpha7
或pi/2
)。如果是这种情况,您只需在阅读&#34; word&#34;之后检查temp
。只有在匹配&#34;非数字&#34;时才增加count
图案。
如果你只想处理数字,那么可能就像没有递增一样简单,如果你想处理小数,指数格式等等,它可能很复杂。
但底线仍然相同:
while(fscanf(fp,"%s",temp) != EOF )
{
if (! isANumber(temp))
count++;
}
具有isANumber
的合适定义。例如,对于仅无符号整数,这样的事情将是一个良好的开端:
int isANumber (char *str) {
// Empty string is not a number.
if (*str == '\0')
return 0;
// Check every character.
while (*str != '\0') {
// If non-digit, it's not a number.
if (! isdigit (*str))
return 0;
str++;
}
// If all characters were digits, it was a number.
return 1;
}
对于更复杂的检查,您可以使用C中的strto*
调用,为它们提供temp
缓冲区,并确保使用endptr
方法来确保扫描整个字符串。在我的头顶,所以不是好测试,这将是:
int isANumber (char *str) {
// Empty string is not a number.
if (*str == '\0')
return 0;
// Use strtod to get a double.
char *endPtr;
long double d = strtold (str, &endPtr);
// Characters unconsumed, not number (things like 42b).
if (*endPtr != '\0')
return 0;
// Was a long double, so number.
return 1;
}
您唯一需要注意的是NaN
或+Inf
等特定字符串被strtold
视为一个数字,因此您可能需要额外检查。
答案 1 :(得分:0)
while(*temp != '\0'){
if(isnumber(*temp))
break;
}
[不要复制完全相同的代码]
答案 2 :(得分:0)
我发现strpbrk
是在 haystack 中搜索多个针的最有用功能之一。您的针集合是数字字符"0123456789"
,如果存在于从文件读取的行中,则将计为一行。我也更喜欢POSIX getline
进行行计数,以正确处理最后一行的非POSIX行结尾的文件(fgets
和wc -l
省略文本(和计数)最后一行,如果它不包含POSIX行结束('\n'
)。也就是说,在一行中搜索作为参数传递的trm
中包含的字符的小函数可以写成:
/** open and read each line in 'fn' returning the number of lines
* continaing any of the characters in 'trm'.
*/
size_t nlines (char *fn, char *trm)
{
if (!fn) return 0;
size_t lines = 0, n = 0;
char *buf = NULL;
FILE *fp = fopen (fn, "r");
if (!fp) return 0;
while (getline (&buf, &n, fp) != -1)
if (strpbrk (buf, trm))
lines++;
fclose (fp);
free (buf);
return lines;
}
只需传递感兴趣的文件名和每行中要搜索的字词即可。默认条件为"0123456789"
的简短测试代码,将文件名作为第一个参数,术语作为第二个参数,可以写成如下:
#include <stdio.h> /* printf */
#include <stdlib.h> /* free */
#include <string.h> /* strlen, strrchr */
size_t nlines (char *fn, char *trm);
int main (int argc, char **argv) {
char *fn = argc > 1 ? argv[1] : NULL;
char *srch = argc > 2 ? argv[2] : "0123456789";
if (!fn) return 1;
printf ("%zu %s\n", nlines (fn, srch), fn);
return 0;
}
/** open and read each line in 'fn' returning the number of lines
* continaing any of the characters in 'trm'.
*/
size_t nlines (char *fn, char *trm)
{
if (!fn) return 0;
size_t lines = 0, n = 0;
char *buf = NULL;
FILE *fp = fopen (fn, "r");
if (!fp) return 0;
while (getline (&buf, &n, fp) != -1)
if (strpbrk (buf, trm))
lines++;
fclose (fp);
free (buf);
return lines;
}
尝试一下,看看这是否是你所期待的,如果没有,请告诉我,我很乐意进一步帮助。
示例输入文件
$ cat dat/linewno.txt
The quick brown fox
jumps over 3 lazy dogs
who sleep in the sun
with a temp of 101
示例使用/输出
$ ./bin/getline_nlines_nums dat/linewno.txt
2 dat/linewno.txt
$ wc -l dat/linewno.txt
4 dat/linewno.txt