使用 fgets/strtok 逐行处理输入文件

问题描述 投票:0回答:1

我正在尝试创建一个 C 程序来处理输入文件并查找字数统计/解剖信息(字数、最长单词的长度、最常见的单词大小及其频率等)。

我大致了解如何做到这一点,但是当使用

fgets
作为循环的条件来逐行处理输入文件时,我的程序甚至从未到达循环体,从而产生意外的结果。

到目前为止我有以下代码:

// This program reads all lines of an input file and generates 
// a report including: 
//      Number of words in the file 
//      Which word size occurs the most and how many times 
//      Largest word length and its frequency 
//      All words of the longest word length of the file 
//       (duplicates not reported)

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

#define MAXW 300    // max total words
#define MAXC 17     // max chars in a word 
#define MAXLINEW 82 // max chars to a line 
#define MAXLINE 30  // max number of lines

const char *clean(char *src); 
int getWords(char (*words)[MAXC], FILE *f);

int main(char **argv) {

    char words[MAXC][MAXW] = {{0}};
    int num_words = 0;
    size_t i;

    FILE *f = fopen("input.txt", "r");

    if (!f) {
        fprintf (stderr, "ERROR: Unable to open file '%s'.\n", argv[1]);
        return 1;
    }

    num_words = getWords(words, f);
    printf("Num words = %d\n", num_words);

    fclose(f);
}

const char *clean(char *src) { 
    char *dst; 
    for (; *src; ++src) { 
        if (!ispunct((unsigned char)*src)) 
            *dst++ = tolower((unsigned char)*src); 
            *dst = 0;
    }
    return dst; 
}

int getWords(char (*words)[MAXC], FILE *f) { 
    int word_cnt = 0; 
    int r; 
    char p = NULL; 
    char lines[MAXLINE][MAXLINEW]; 
    char buf[MAXLINEW]; 
    static const char delims[] = " \n"; 
    r = 0; 
    while (fgets(buf, MAXLINEW, f)) { 
        // find the next word 
        if (p == NULL) { 
            p = strtok(buf, delims); 
            while (p) { 
                const char c = clean(p); 
                strcpy(words[word_cnt], c); 
                word_cnt++; 
                p = strtok(NULL, delims); 
            } 
        } 
    } 
}

我尝试使用

fgets
分割输入文件的每一行,然后使用
strtok
处理每一行以获取每个单词(由换行符空格分隔)。通过
strtok
对每个单词进行标记,我想将其传递给
clean
函数,该函数应该删除所有标点符号并将所有内容设为小写。清理单词后,我想将清理后的单词复制到所有单词的最终数组中,稍后我可以使用它来生成该程序所需的结果(计算单词长度/频率等)。

正如我之前所说,我的程序甚至从未到达

getWords
内部的 while 循环体,我不知道为什么。

我对 C 没有太多经验,但我确实了解 C++,所以如果我的代码缺少任何明显的东西,我很抱歉。

任何帮助将不胜感激,谢谢!

c fgets strtok
1个回答
0
投票

明显的错误是您将 clean 中单词的

cleaned
版本存储到
*dst
,但该指针未初始化。

您应该就地修改源数组:

char *clean(char *src) { 
    char *result = src; 
    char *dst = src; 
    for (; *src; ++src) { 
        if (!ispunct((unsigned char)*src)) 
            *dst++ = tolower((unsigned char)*src); 
    }
    *dst = '\0';
    return result; 
}

又一个错误:

const char c = clean(p);
应该是

const char *c = clean(p);
© www.soinside.com 2019 - 2024. All rights reserved.