2015-05-26 5 views
0

Я новичок в программировании, поэтому, пожалуйста, будь красивой.C - Печать определенной строки из текстового файла

В настоящее время я пытаюсь написать программу, которая открывает текстовый файл, читается двумя словами, поиск в текстовом файле подсчитывает, сколько раз появляются два слова, а затем, наконец, печатает первую строку, в которой появилось первое слово на.

До сих пор это то, что я сделал:

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

FILE *infile; 
char inputWord1[100], inputWord2[100], filename[100], wordInText[100], line[500]; 
int i, count, strComp, word1Count, word2Count, wordLen, lineCount; 
char c; 

int main() { 
    printf("Enter the first word: "); 
    gets(inputWord1); 
    printf("Enter the second word: "); 
    gets(inputWord2); 
    printf("Enter the file name: "); 
    gets(filename); 

    infile = fopen(filename, "r"); 
    if(infile == NULL) { 
     printf("Error"); 
     exit(1); 
    } 

    word1Count = 0; word2Count = 0; lineCount = 1; 
    while(fscanf(infile, "%s", wordInText) != EOF) { 
     wordLen = strlen(wordInText); 
     for(i = 0; i < wordLen; i++) { 
      if(wordInText[i] >= 65 && wordInText[i] <= 90) { 
       wordInText[i] = wordInText[i] + 32; 
      } 
     } 

     for(c = getc(infile); c != EOF; c = getc(infile)) { 
      if(c == '\n') { 
       lineCount = lineCount + 1; 
      } 
     } 

     strComp = strcmp(wordInText, inputWord1); 
     if(strComp == 0) { 
      word1Count++; 
      if(word1Count == 1) { 
       for(int x = lineCount; x <= lineCount; x++) { 
        fgets(line, 500, infile); 
        printf("%s\n", line); 
       } 
      } 
     } 
     strComp = strcmp(wordInText, inputWord2); 
     if(strComp == 0) { 
      word2Count++; 
     } 
    } 
    printf("Word 1 appears %d times\n", word1Count); 
    printf("Word 2 appears %d times\n", word2Count); 
} 

Так что все это работает, кроме:

strComp = strcmp(wordInText, inputWord1); 
     if(strComp == 0) { 
      word1Count++; 
      if(word1Count == 1) { 
       for(int x = lineCount; x <= lineCount; x++) { 
        fgets(line, 500, infile); 
        printf("%s\n", line); 
       } 
      } 
     } 

Последний цикл не работает должным образом. Он печатает \ n, но не печатает строку. Я действительно не знаю, почему он не работает. Все остальные части работают нормально.

Если у кого-то есть идеи о том, как разрешить это, я был бы очень признателен. Пожалуйста, имейте в виду, что я знаю только основные функции C, и я не полностью закончил эту программу (все равно нужно преобразовать введенные слова в нижний регистр).

+1

Вы уверены, что хотите 'для (INT х = LineCount; х <= LineCount; х ++)'? – timrau

+0

Вам необходимо отсканировать файл по строкам. Дублируйте первую строку. Затем отобразите количество слов и, наконец, выведите дубликат строки. –

+0

'gets()' is bad, используйте 'fgets()' slways. :-) –

ответ

0

следует заменить, чтобы избежать переполнения буфера Я использовал некоторое определение, когда мы находим слово, что строка ввода является dup и печатается в конце. Файл считывается по строкам, каждая строка разделяется по слову. Синтаксические должны быть обновлены, позволяет несколько пространств, например, поддерживают больше слов разделителя и т.д. ...

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

#define WORD_LEN_MAX 100              
#define LINE_LEN_MAX 500              

int main() {                 
    FILE *infile;                
    char inputWord1[WORD_LEN_MAX], inputWord2[WORD_LEN_MAX];     
    char filename[WORD_LEN_MAX];            
    char wordInText[WORD_LEN_MAX], line[LINE_LEN_MAX];       
    char firsAppear[LINE_LEN_MAX];            
    int word1Count, word2Count, lineCount, i;         
    printf("Enter the first word: ");           
    gets(inputWord1);               
    printf("Enter the second word: ");           
    gets(inputWord2);               
    printf("Enter the file name: ");           
    gets(filename);                


    infile = fopen(filename, "r");            
    if(infile == NULL) {              
     printf("Error cannot open %s", filename);        
     exit(1);                
    }                   

    word1Count = 0; word2Count = 0; lineCount = 1;        
    while(fgets(line, sizeof(line), infile) != NULL) {       
     char *p = line;               
     lineCount++;               
     while (*p != '\0' && *p != '\n') {          
      i = 0;                
      while (*p != ' ' && *p != '\0' && *p != '\n') {      
       wordInText[i++] = tolower(*p++);        
      }                 
      if (*p == ' ') {             
       p++;               
      }                 
      wordInText[i] = '\0';            

      if(!strcmp(wordInText, inputWord1)) {        
       word1Count++;             
       if(word1Count == 1) {           
        strncpy(firsAppear, line, sizeof(firsAppear));    

       }                
      }                 
      if(!strcmp(wordInText, inputWord2)) {        
       word2Count++;             
      }                 
     }                  
    }                   
    printf("Word 1 appears %d times\n", word1Count);       
    printf("Word 2 appears %d times\n", word2Count);       
    printf("%s", firsAppear);             
} 
+0

Спасибо, что нашли время ответить на мой вопрос. Это именно то, что мне нужно, очень ценим! :) – RussNZ

+0

Просто быстрый вопрос, если вы не возражаете: Почему вы используете '#define WORD_LEN_MAX 100', а затем' arrayName [WORD_LEN_MAX 100] 'вместо' arrayName [100] '? Просто любопытно, потому что я никогда не учил этому. Есть ли какое-либо преимущество в определении максимального размера только для записи в максимальном размере массива? Еще раз спасибо. – RussNZ

+0

С помощью этого решения, если вы хотите изменить размер, вам нужно убрать только одну строку, и он добавляет некоторую информацию о том, что это 100 или 500 –

0

Есть много способов сделать это. Однако выбранный вами подход должен быть направлен на более сложный конец спектра. При поиске правильных инструментов для использования при чтении строк с использованием ориентированных на линию вход почти всегда является правильным выбором. Таким образом, gets является никогда надлежащего выбора. Он ужасно небезопасен и был удален из библиотеки C, вместо этого используйте fgets (или getline).

Избегайте использования глобальных переменных . Они не используются в вашей программе. Для них ограниченное использование, но для простых программ вы почти никогда не будете их использовать.

Если вам нужно сравнить слова и суммировать количество совпадений, просто сделайте это ... Сравните и если они совпадают с приращением суммы. Больше ничего не требуется.

Что касается lineCount, если вы используете ориентированный на линию вход, это тривиально, просто увеличивайте счетчик для каждой прочитанной строки.

Но как получить слова для проверки? strtok (или strsep) - это предоставленные инструменты. Просто прочитайте строку и tokenize it. Затем просто сравните и увеличьте.

Я собрал короткий пример. (большая часть кода просто снимает newline с конца ввода). Это просто, прочитайте строку, отметьте, сравните и увеличьте совпадение, увеличьте значение lineCount.Готово:

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

/* Avoid Globals */ 

#define MAXL 500 
#define MAXW 100 

int main (void) 
{ 
    char inputWord1[MAXW] = { 0 };  /* Always Initialize your Variables */ 
    char inputWord2[MAXW] = { 0 }; 
    char filename[MAXW] = { 0 }; 
    char line[MAXL] = { 0 }; 
    char *token = NULL; 
    char *delim = " ,.;\n"; 
    size_t word1Count = 0;    /* can't be negative, use */ 
    size_t word2Count = 0;    /* size_t or unsigned  */ 
    size_t lineCount = 0; 
    size_t len = 0; 
    FILE *infile = NULL; 

    printf ("\nEnter the first word: ");  /* Do NOT use gets, it is insecure */ 
    fgets (inputWord1, MAXW, stdin);   /* use fgets or getline instead  */   

    len = strlen (inputWord1); 
    while (len > 0 && (inputWord1[len-1] == '\n' || inputWord1[len-1] == '\r')) 
     inputWord1[--len] = 0;     /* strip newline or carriage return */ 

    printf ("\nEnter the second word: "); 
    fgets (inputWord2, MAXW, stdin); 

    len = strlen (inputWord2); 
    while (len > 0 && (inputWord2[len-1] == '\n' || inputWord2[len-1] == '\r')) 
     inputWord2[--len] = 0;     /* strip newline or carriage return */ 

    printf ("\nEnter the file name: "); 
    fgets (filename, MAXW, stdin); 

    len = strlen (filename); 
    while (len > 0 && (filename[len-1] == '\n' || filename[len-1] == '\r')) 
     filename[--len] = 0;     /* strip newline or carriage return */ 

    infile = fopen (filename, "r"); 
    if (infile == NULL) { 
     printf ("error: file open failed. '%s'\n", filename); 
     exit (1); 
    } 

    printf ("\nThe lines processed are:\n\n"); 

    /* read each line, tokenize, compare and increment */ 
    while (fgets (line, MAXL, infile) != NULL) 
    { 
     len = strlen (line); 
     while (len > 0 && (line[len-1] == '\n' || line[len-1] == '\r')) 
      line[--len] = 0;     /* strip newline or carriage return */ 

     printf (" %2zu %s\n", lineCount, line); 
     for (token = strtok (line, delim); token != NULL; token = strtok (NULL, delim)) 
     { 
      if (strcmp (token, inputWord1) == 0) 
       word1Count++; 
      if (strcmp (token, inputWord2) == 0) 
       word2Count++; 
     } 

     lineCount++; 
    } 

    printf ("\nWord 1 appears %zu times\n", word1Count); 
    printf ("Word 2 appears %zu times\n", word2Count); 
    printf ("Number of lines: %zu\n\n", lineCount); 

    return 0; 
} 

Использование/выход

$ ./bin/countw1w2 

Enter the first word: me 

Enter the second word: chequer 

Enter the file name: dat/ll_replace_poem.txt 

The lines processed are: 

    0 Eye have a spelling chequer, 
    1 It came with my Pea Sea. 
    2 It plane lee marks four my revue, 
    3 Miss Steaks I can knot sea. 
    4 Eye strike the quays and type a whirred, 
    5 And weight four it two say, 
    6 Weather eye am write oar wrong, 
    7 It tells me straight aweigh. 
    8 Eye ran this poem threw it, 
    9 Your shore real glad two no. 
    10 Its vary polished in its weigh. 
    11 My chequer tolled me sew. 
    12 A chequer is a bless thing, 
    13 It freeze yew lodes of thyme. 
    14 It helps me right all stiles of righting, 
    15 And aides me when eye rime. 
    16 Each frays come posed up on my screen, 
    17 Eye trussed too bee a joule. 
    18 The chequer pours over every word, 
    19 Two cheque sum spelling rule. 

Word 1 appears 4 times 
Word 2 appears 4 times 
Number of lines: 20 
+0

Спасибо, что помогли мне действительно оценить, что вы не торопитесь с этим. Я очень многому научился с вашего поста! Я бы поднял голову, если бы мог (не хватало репутации). – RussNZ

+0

Не проблема, просто рада помочь. Существует много способов подхода к решению большинства проблем в C. Это, вероятно, стандартный способ сделать это, но нет абсолютно ничего плохого в том, как вы к нему подошли. Удачи вам в вашем коде. –