C隔离"只有字符串"在文本文件中

时间:2016-01-12 23:53:43

标签: c parsing

我有一个文本文件,其中有1个单词后跟~100个浮点数。浮点数由空格,制表符或换行符分隔。此格式在整个文本文件中重复多次。

例如,这就是文本文件的样子:

one 0.00591 0.07272 -0.78274 ... 
0.0673 ...
0.0897 ...
two 0.0654 ...
0.07843 ...
0.0873 ...
three ...
...
...

我的问题是,如何计算文件中的单词数量,我尝试使用fscanf但是一旦读取第一个单词,之后我必须跳过所有浮点数直到下一个单词。

非常感谢任何帮助。

感谢。

4 个答案:

答案 0 :(得分:5)

我将为您提供一个可能的解决方案的高级概述,让您自己弄清楚如何将其转换为C语言。

  • 使用零来初始化单词(非数字)的计数器。
  • 逐行阅读文件。对于每一行,重复以下步骤:
    • 将行标记为以空格分隔的单词。对于每个单词,请重复以下操作:
      • 如果单词可以解析为数字,则不执行任何操作并继续。
      • 否则,递增计数器。

您可能会发现一些有用的库函数:

  • getline读取一行输入。它不是官方标准库的一部分,而是作为许多实现的扩展提供的,包括GNU的libc。如果您没有,可以使用fgetsrealloc自行推送。
  • strtok标记一个字符串,虽然使用起来有点尴尬。如果您想自己标记,您会发现isspace有用。您将需要用NUL字节替换空白字符,以便将它们之间的字符视为单个NUL终止字符串。
  • strtod尝试将字符数组解析为double

您可以实现自己的小有限自动机,而不是使用库函数将数字解析为double。这是自动机理论中的经典教学实例。请参阅示例this lecture(向下滚动“浮点数的语言”)。

答案 1 :(得分:2)

这是一种逐字逐句的方法(不需要缓冲)。我很确定逻辑是合理的。

#include <stdio.h>

int is_alpha(char c)
{
    //only works for some character encodings
    return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
}
int main(void)
{
    FILE *file_ptr;
    int character;
    int prev_char_was_letter = 0;
    int word_count = 0;
    file_ptr = fopen("my_file.txt", "r");
    if (!file_ptr) 
    { 
        fprintf(stderr, "can't open file\n");
        return 1;
    }
    character = fgetc(file_ptr);
    while (character != EOF)
    {
        if (is_alpha(character) && !prev_char_was_letter) 
        {
            word_count++;
            prev_char_was_letter = 1;
        }
        else if (!is_alpha(character))
        {
            prev_char_was_letter = 0;
        }
        character = fgetc(file_ptr);
    }
    printf("%d\n", word_count);
    fclose(file_ptr);
}

答案 2 :(得分:1)

已经建议的替代解决方案是使用strtok()进行分隔和isalpha()函数。这是一个完成工作的程序示例。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

char delim[4]={' ','\t',0x0a,0x0d};
#define MAX_LINE 1024

int isaword(char *);

int main(int argc,char **argv)
{
    FILE *fp;
    char line[MAX_LINE];
    char *s;
    int wcnt=0;

    if(argc==1)
    {
        fp = stdin;
    }
    else
    {
        fp = fopen(argv[1],"r");
    }
    if(fp==0)
    {
        return -1; ///file not found
    }
    while(!feof(fp))
    {
        s=fgets(line,MAX_LINE,fp);
        if(s)
        {
            s=strtok(line,delim);
            while(s!=NULL)
            {
                if(isaword(s))
                {
                    wcnt++;
                }
                s=strtok(NULL,delim);    
            }
        }
    }
    fclose(fp);
    printf("word count = %d",wcnt);
    return 0;
}

int isaword(char *w)
{
    int result = 1;
    int i;
    for(i=0;i<strlen(w);i++)
    {
        result = isalpha(w[i]);
        if(result==0)
        {
            break;
        }
    }
    return result;
}

解决方案中的免责声明 - “单词”的定义基于函数isalpha

答案 3 :(得分:0)

您可以这样做:

void foo() {
    FILE *file = fopen("file.txt", "r");
    char buffer[10000]; // your choice
    while(fscanf(file, "%s", buffer) > 0) {
        int i = 0;
        int word = 0;
        int number_of_dots = 0;
        while(i < strlen(buffer)) {
            if(!isdigit(buffer[i]) && buffer[i] != '.') {
                if(!(i == 0 && buffer[i] == '-')) {
                    word = 1;
                    break;
                }

            }
            if(buffer[i] == '.') number_of_dots++;
            i++;
        }
        if(word || number_of_dots > 1) {
            printf("%s ", buffer);
            puts("It's a word!");
        }
    }
}