繁体   English   中英

C-从文本文件打印特定行

[英]C - Print Specific Line From Text File

我是编程新手,所以请保持友好。

当前,我正在尝试编写一个程序来打开一个文本文件,读取两个单词,搜索该文本文件以计算两个单词出现的次数,然后最终打印出第一个单词出现的第一行。

到目前为止,这是我所做的:

#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);
                }
            }
        }

最后一个for循环无法正常工作。 它打印出\\ n,但不打印该行。 我真的不知道为什么它不起作用。 所有其他部分都工作正常。

如果有人对如何解决这个问题有任何想法,我将不胜感激。 请记住,我只知道基本的C函数,并且我还没有完全完成该程序(仍然需要将输入的单词转换为小写)。

应该替换gets以避免缓冲区溢出。我使用了一些define,当我们找到输入行是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);                                                  
}

有很多方法可以做到这一点。 但是,您选择的方法必须朝着更困难的方向发展。 在寻找正确的工具来使用时,在读取线时 ,使用面向行的输入几乎总是正确的选择。 因此, gets 永远不是正确的选择。 它非常不安全,已从C库中删除,请改用fgets (或getline )。

避免使用全局变量 在您的程序中没有用。 它们的用途有限,但是对于简单的程序,您几乎永远不会使用它们。

当您需要比较单词并将匹配项的总数相加时,只需执行...比较,如果它们匹配,就可以增加总和。 没有其他要求。

至于lineCount如果您使用的是面向行的输入,这是微不足道的,只需为读取的每一行增加计数器。

但是,如何使单词测试呢? strtok (或strsep )是提供的工具。 只需阅读一行并将其标记化即可 然后比较并递增。

我举了一个简短的例子。 (大多数代码只是从输入末尾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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM