C:文本文件中出现字母

-1 c

程序通过命令行获取输入文件,并输出文本文件中每个字母的出现位置.不知道我哪里出错了.

int main(int argc, char *argv[]) {
    char word[1000];
    int a = 0;
    int b = 0;
    int d = 0;
    int c = 0;
    int e = 0;
    int f = 0;
    int g = 0;
    int h = 0;
    int i = 0;
    int j = 0;
    int k = 0;
    int l = 0;
    int m = 0;
    int n = 0;
    int o = 0;
    int p = 0;
    int q = 0;
    int r = 0;
    int s = 0;
    int t = 0;
    int u = 0;
    int v = 0;
    int w = 0;
    int x = 0;
    int y = 0;
    int z = 0;

    int other = 0;

    int counter, lenght;

    FILE *fp = fopen(argv[1], "r");

    fgets(word, 999, fp);

    lenght = 1000;
    for(counter = 0; counter < lenght; counter++) {
        word[counter] = tolower(word[counter]);
        if (word[counter] == 'a') {
            a++;
        }
        else if (word[counter] == 'b') {
            b++;
        }
        else if (word[counter] == 'c') {
            c++;
        }
        else if (word[counter] == 'd') {
            d++;
        }
        else if (word[counter] == 'e') {
            e++;
        }
        else if (word[counter] == 'f') {
            f++;
        }
        else if (word[counter] == 'g') {
            g++;
        }
        else if (word[counter] == 'h') {
            h++;
        }
        else if (word[counter] == 'i') {
            i++;
        }
        else if (word[counter] == 'j') {
            j++;
        }
        else if (word[counter] == 'k') {
            k++;
        }
        else if (word[counter] == 'l') {
            l++;
        }
        else if (word[counter] == 'm') {
            m++;
        }
        else if (word[counter] == 'n') {
            n++;
        }
        else if (word[counter] == 'o') {
            o++;
        }
        else if (word[counter] == 'p') {
            p++;
        }
        else if (word[counter] == 'q') {
            q++;
        }
        else if (word[counter] == 'r') {
            r++;
        }
        else if (word[counter] == 's') {
            s++;
        }
        else if (word[counter] == 't') {
            t++;
        }
        else if (word[counter] == 'u') {
            u++;
        }
        else if (word[counter] == 'v') {
            v++;
        }
        else if (word[counter] == 'w') {
            w++;
        }
        else if (word[counter] == 'x') {
            x++;
        }
        else if (word[counter] == 'y') {
            y++;
        }
        else if (word[counter] == 'z') {
            z++;
        }
        else {
            other++;
        }
    }
    printf("\nCharacter frequency in %s", argv[1]);
    printf("\nCharacter   Count");
    printf("\na \t\t %d", a);
    printf("\nb \t\t %d", b);
    printf("\nc \t\t %d", c);
    printf("\nd \t\t %d", d);
    printf("\ne \t\t %d", e);
    printf("\nf \t\t %d", f);
    printf("\ng \t\t %d", g);
    printf("\nh \t\t %d", h);
    printf("\ni \t\t %d", i);
    printf("\nj \t\t %d", j);
    printf("\nk \t\t %d", k);
    printf("\nl \t\t %d", l);
    printf("\nm \t\t %d", m);
    printf("\nn \t\t %d", n);
    printf("\no \t\t %d", o);
    printf("\np \t\t %d", p);
    printf("\nq \t\t %d", q);
    printf("\nr \t\t %d", r);
    printf("\ns \t\t %d", s);
    printf("\nt \t\t %d", t);
    printf("\nu \t\t %d", u);
    printf("\nv \t\t %d", v);
    printf("\nw \t\t %d", w);
    printf("\nx \t\t %d", x);
    printf("\ny \t\t %d", y);
    printf("\nz \t\t %d", z);
    fclose(fp);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

应该输出两列,一列是字母,下一列是该字母出现的次数

chq*_*lie 5

您的代码中存在问题:

  • 你不包括<stdio.h>也不<ctype.h>

  • 你只读了一行,你甚至不检查是否成功.你应该写一个循环while (fgets(word, sizeof word, fp)) {

  • 你检查word数组中的所有字符:你应该在行的末尾停止:lenght = strlen(word);

  • tolower()不应该给出一个char参数,因为在char签名的平台上,负值会调用未定义的行为.您可以抛出参数(unsigned char)以避免这种情况:word[counter] = tolower((unsigned char)word[counter]);

更多改进空间:

  • lenght是错误的,它应该是length.

  • 你应该使用一组计数器来避免所有这些测试和所有这些显式printf语句.

  • 检查参数计数和fopen()成功

  • 无需逐行读取,一次处理一个字节读取getc().但是,一次读取一个大块可能会更快,因为它使用较少的测试和锁定.

  • printf声明应在末尾,而不是在开始输出换行符.

这是一个更正和简化的版本:

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

int main(int argc, char *argv[]) {
    int count[UCHAR_MAX + 1] = { 0 };
    int other, total;
    int c;
    const char *s;
    FILE *fp;

    if (argc <= 1) {
        fprintf(stderr, "missing input file\n");
        return 1;
    }
    fp = fopen(argv[1], "r");
    if (fp == NULL) {
        fprintf(stderr, "cannot open input file %s\n", argv[1]);
        return 1;
    }

    total = 0;
    while ((c = getc(fp)) != EOF) {
        count[tolower(c)] += 1;
        total++;
    }

    printf("Character frequency in %s\n", argv[1]);
    printf("Character   Count\n");
    other = total;
    for (s = "abcdefghijklmnopqrstuvwxyz"; *s; s++) {
        printf("%c:\t%9d\n", *s, count[(unsigned char)*s]);
        other -= count[(unsigned char)*s];
    }
    printf("other:\t%9d\n", other);
    fclose(fp);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

通过块而不是一个字节一次读取文件可以显着提高最近C库的速度,因为对多线程的支持使得getc()宏效率低下.使用64K缓冲区,对于400MB文件,下面的代码快50倍(50倍):

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

#define BUFFER_SIZE 65536
int main(int argc, char *argv[]) {
    unsigned char buffer[BUFFER_SIZE];
    long count[UCHAR_MAX + 1] = { 0 };
    long other;
    size_t i, n;
    const char *s;
    FILE *fp;

    if (argc <= 1) {
        fprintf(stderr, "missing input file\n");
        return 1;
    }
    fp = fopen(argv[1], "r");
    if (fp == NULL) {
        fprintf(stderr, "cannot open input file %s\n", argv[1]);
        return 1;
    }

    while ((n = fread(buffer, 1, sizeof buffer, fp)) != 0) {
        for (i = 0; i < n; i++) {
            count[buffer[i]] += 1;
        }
    }
    other = 0;
    for (i = 0; i <= UCHAR_MAX; i++) {
        if (isupper(i)) {
            count[tolower(i)] += count[i];
        } else {
            if (!islower(i))
                other += count[i];
        }
    }

    printf("Character frequency in %s\n", argv[1]);
    printf("Character   Count\n");
    for (s = "abcdefghijklmnopqrstuvwxyz"; *s; s++) {
        printf("%c:\t%9ld\n", *s, count[(unsigned char)*s]);
    }
    printf("other:\t%9ld\n", other);
    fclose(fp);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)