2016-01-12 3 views
4

У меня есть текстовый файл, в котором есть 1 слово, за которым следует ~ 100 чисел с плавающей запятой. Номера с плавающей точкой разделяются пробелом, вкладкой или новой строкой. Этот формат повторяется несколько раз в текстовом файле.C Изолировать «только строки» в текстовом файле

Например, это то, что текстовый файл выглядит следующим образом:

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

Мой вопрос, как я могу подсчитать количество слов в файле, я попытался с помощью fscanf, но как только он читает первое слово , после этого я должен пропустить все поплавки до следующего слова.

Любая помощь будет высоко оценена.

Спасибо.

+7

Почему вы ограничиваете себя c? Проблемы, подобные этим, могут быть намного проще решены с помощью awk, perl, ... Это будет вариант? –

+3

Показать текущий код. – mikedu95

+0

, как предложил @DirkHerrmann, с чем-то другим будет проще, если только C, если только вы не должны делать домашнее задание на C, вы также можете сделать что-то вроде команды 'wc', чтобы выполнить задание, если хотите просто подсчитать слова. – vmonteco

ответ

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); 
} 
+0

@BLUEPIXY один год позже, но делаем. благодаря – Ben

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!"); 
     } 
    } 
} 
5

Я дам вам обзор высокого уровня возможного решения давая вам понять себя, как перевести, что в С.

  • Инициализировать счетчик количества слов (не числа) с нулем.
  • Прочитайте файл по строкам. Для каждой строки повторите следующее:
    • Токенизировать линию в отдельные пробелы. Для каждого слова повторите следующее:
      • Если слово может быть проанализировано в число, ничего не делайте и продолжайте.
      • В противном случае увеличивайте счетчик.

Некоторые функции библиотеки, которые могут оказаться полезными:

  • getline читать одну строку ввода. Он не является частью официальной стандартной библиотеки, но предоставляется как расширение многими реализациями, включая libc GNU. Если у вас его нет, вы можете свернуть самостоятельно, используя fgets и realloc.
  • strtok tokenize строка, хотя она немного неудобна в использовании. Если вы хотите токенизировать себя, вы найдете isspace полезным. Вы захотите заменить символы пробела на NUL-байты, чтобы вы могли обрабатывать символы между ними как отдельные строки, завершенные NUL.
  • strtod, чтобы попытаться разобрать массив символов в double.

Вместо использования библиотечной функции для разбора числа в double вы также можете реализовать свой собственный небольшой конечный автомат. Это классический пример обучения в теории автоматов. См. Например, this lecture (прокрутите вниз для «Язык чисел с плавающей запятой»).

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.

Смежные вопросы