计算文本文件中的字符用法? C

时间:2017-10-19 17:16:17

标签: c character text-files counter toupper

嗨,
我需要计算一些纯文本文件中字母字符的用法。这就是我的意思。基本上只需运行文本文件,并将每个字符与特定搜索字符的ASCII值进行比较。
当我运行它时,我所能看到的只是第一个printf()字符串,并且当我关闭控制台时只是终止状态的错误。
我在.exe文件所在的文件夹中有一个text.txt文件,但我看不到任何内容。

不确定我的语法是坏还是语义。
求救! : - )

#include <stdio.h>
#include <stdlib.h>
#define ASCIIstart 65 
#define ASCIIend 90

void main(){
    FILE *fopen(), *fp;
    int c;
    unsigned int sum;

    fp = fopen("text.txt","r");

    printf("Characters found in text: \n");

    for (int i = ASCIIstart; i <= ASCIIend; i++){
        sum = 0;
        c = toupper(getc(fp));
        while (c != EOF){
            if (c == i){
                sum = sum++;
            }
            c = toupper(getc(fp));
        }
        if (sum > 0){
            printf("%c: %u\n",i,sum);
        }
    }
    fclose(fp);
}

6 个答案:

答案 0 :(得分:1)

不是为每个角色查找整个文件,而是

FILE *fp;
int c, sum[ASCIIend - ASCIIstart + 1]={0};
fp = fopen("file.txt,"r");
if(fp==NULL)
{
    perror("Error");
    return 1;
}

int i;
while( (c = toupper(getc(fp)))!= EOF)
{
    if(c>=ASCIIstart && c<=ASCIIend)
    {
        sum[c-ASCIIstart]++;
    }
}
for(i=ASCIIstart; i<=ASCIIend; ++i)
{
    printf("\n%c: %d", i, sum[i-ASCIIstart]);
}

您必须检查fopen()的返回值,以确保文件已成功打开。

有一个数组sum,它保存了用ASCIIendASCIIstart宏表示的范围内每个字符的出现次数。

数组的大小就是要计算出现次数的字符数。

使用

sum[c-ASCIIstart]是因为cASCIIstart的ASCII值(如果编码确实是ASCII)之间的差异将给出与c相关联的索引。 / p>

我不知道您对FILE *fopen(), fp;的意思,但fopen()是用于打开文件的C函数的名称。

并通过

FILE *fopen(), *fp;

你给了一个函数原型fopen()

但在stdio.h中,已经有fopen()的原型

FILE *fopen(const char *path, const char *mode);

但是没有显示错误(如果是这样),因为fopen()表示该函数可以包含任意数量的参数。看看here

如果FILE *fopen();的返回类型不是FILE *,或者如果它显示给int等其他参数类型,则肯定会出错。

并且,void main()不被视为良好做法。请改用int main()。看here

答案 1 :(得分:1)

您可以使用字符数组并通过一次遍历来解析文件内容,并最终显示数组计数。

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

void main(){
FILE *fopen(), *fp;
int c;
fp = fopen("test.txt","r");
printf("Characters found in text: \n");
char charArr[26]= {0};
c = toupper(fgetc(fp));

while(c!=EOF) {
  charArr[c-'A']=charArr[c-'A']+1;
  c = toupper(fgetc(fp));
}
fclose(fp);
for(int i=0;i<26;i++){
   printf("\nChar: %c | Count= %d ",i+65,charArr[i]);
}
}

希望这会有所帮助!!

答案 2 :(得分:0)

因为在你第一次结束文件之后。 你的c = toupper(getc(fp));之后返回-1。

答案 3 :(得分:0)

对于只计算一个字符,您正在读取整个文件并为每个字符重复此操作。相反,你可以这样做:

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

#define ASCIIstart 65 
#define ASCIIend 90

int main(){
    FILE  *fp;
    int c, i;
    int alphabets[26] = {0};

    fp = fopen("text.txt","r");
    if (fp == NULL){
        fprintf (stderr, "Failed to open file\n");
        return -1;
    }

    while ((c = toupper(fgetc(fp))) != EOF){
        if (c >= ASCIIstart && c <= ASCIIend)
            alphabets[c - ASCIIstart]++;
    }

    fclose(fp);
    fprintf(stdout, "Characters found in text: \n");
    for (i = 0; i < 26; i++)
        fprintf (stdout, "%c: %d\n", i+ASCIIstart, alphabets[i]);
    return 0;
}

答案 4 :(得分:0)

TLDR

使用您的代码,您的循环是由内到外的。

我将以伪代码回答,以保持概念简单明了。

现在你正在这样做:

 FOR LETTER = 'A' TO 'Z': 
      WHILE FILE HAS CHARACTERS
           GET NEXT CHARACTER
           IF CHARACTER == LETTER 
                ADD TO COUNT FOR CHAR
           END IF
      END WHILE
 END FOR

问题是你正在运行带有字符A&#39; A&#39;然后到达文件的末尾,这样就不会为B&#39; ...&#39; Z&#39;

做任何事情。

如果换了这个:

 WHILE FILE HAS CHARACTERS
      GET NEXT CHARACTER 
          FOR LETTER = 'A' TO 'Z'
              IF LETTER = UCASE(CHARACTER)
                   ADD TO COUNT FOR LETTER
              END IF
          END FOR
 END WHILE

显然,对每个字母进行26次检查太多,所以也许是一种更好的方法。

 LET COUNTS = ARRAY(26) 

 WHILE FILE HAS CHARACTERS
         CHARACTER := UCASE(CHARACTER)
         IF CHARACTER >= 'A' AND CHARACTER <= 'Z'
            LET INDEX = CHARACTER - 'A'
            COUNTS[INDEX]++
         ENDIF
 END WHILE

您可以将伪代码翻译为C作为练习。

答案 5 :(得分:-1)

在for循环结束时将指针倒回到文件的开头?

之前已发布:Resetting pointer to the start of file

P.S。 - 也许使用数组作为输出值:int charactercount [pow(2,sizeof(char))]这样你就不必重复解析文件了?

编辑:缺少pow()