计算包含数字的文本文件中的字符串数

时间:2016-06-29 05:53:22

标签: c string file

我只想计算文本文件中包含数字的字符串数。但是下面的代码甚至将文件中的数字计为字符串。我该如何纠正这个问题?

int count;
char *temp;
FILE *fp;

 fp = fopen("multiplexyz.txt" ,"r" );

 while(fscanf(fp,"%s",temp) != EOF )
 {
     count++;
 }

 printf("%d ",count);
 return 0;

}

3 个答案:

答案 0 :(得分:1)

好吧,首先,使用temp指针而没有后备存储,这将会让你感到痛苦。

我建议首先使用类似char temp[1000]之类的内容,但请注意,如果您的字数超过一千个字符,那么它仍然有点风险(&& #39;与您提出的问题存在不同的问题,因此我会提及它,但不会花太多时间修复它。< / p>

其次,您似乎想要计算带有数字的字词(例如alpha7pi/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循环中,循环遍历字符串以检查其中的任何字符是否为数字。类似的东西:

while(*temp != '\0'){
       if(isnumber(*temp))
           break;
}

[不要复制完全相同的代码]

答案 2 :(得分:0)

我发现strpbrk是在 haystack 中搜索多个的最有用功能之一。您的集合是数字字符"0123456789",如果存在于从文件读取的行中,则将计为一行。我也更喜欢POSIX getline进行行计数,以正确处理最后一行的非POSIX行结尾的文件(fgetswc -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