ASCIIコードの文字をカウント

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
a_to_b

ASCIIコードの文字をカウント

#1

投稿記事 by a_to_b » 18年前

textファイルの文字の頻度をカウントするプログラムを作っているのですが、
課題では文字の種類はASCIIコードに限られていて、改行コードなど特殊文字も
一つの文字として扱わなければならないのですが、その特殊文字の数え方が分かりません。
一応、自分でやってみたのですが印字な可能な文字しか数えることが出来ませんでした(^_^;)
よろしくお願いします。
#include <stdio.h>
#include <stdlib.h>

int data[256];

void countLtr(FILE *fp);

int main(void)
{
	FILE *fp;
	int c;

	//強制終了
	if ((fp = fopen("test.txt", "r")) == NULL) {
		fprintf ( stderr, "Can't open.\n" );
		exit (2);
	}
	printf("test.txt\n");
	
	countLtr(fp) ;

	printf("---------\n");
		for (c = 0; c <= 127; c++){
		printf("%c:%d\t",  c, data[c] );
	}
	
	fclose(fp);
	
	return 0;
}
	
//ファイル中の英文字の出現頻度を調べる関数
void countLtr(FILE *fp)
{
	int c;

	while ((c = getc(fp)) != EOF)
		if (c >= 0 && c <= 127){
			data[c]++;
		}
}

Justy

Re:ASCIIコードの文字をカウント

#2

投稿記事 by Justy » 18年前

印字な可能な文字しか数えることが出来ませんで
 カウント処理はほぼ正しく出来ています。

 ほぼといったのは fopenのところで モード指定が "r"になっているので改行コードの一部が
変化・欠落する可能性があるからです。


 次に、表示時の問題があります。
 表示できない文字を %cで表示しようとして失敗しているようです。

 for文の中で、それが表示できるかどうか調べて、出来ない場合は例えば以下のように
[color=#d0d0ff" face="monospace]
            if(isprint(c))
                printf(" %2c : %d\t",  c, data[c] );
            else
                printf("[%02x]: %d\t", c, data[c] );[/color]
 表示してみてはどうでしょうか。

管理人

Re:ASCIIコードの文字をカウント

#3

投稿記事 by 管理人 » 18年前

Justyさんのおっしゃる内容でこちらでプログラムを書いてみたところきちんと表示されました。

後、配列の中身が初期化されていないので、宣言時
int data[256];

int data[256]={};
と書けばよいのではないでしょうか。


表示文字かどうかを判別する関数
isprintf

#include <ctype.h>
をインクルードする必要があります。
http://www.google.co.jp/search?hl=ja&q=isprint&lr=
この辺参考にどうぞ。

後、ループの中身を
printf("%c:%d\t",  c, data[c] );

から

        if(isprint(c))
            printf(" %2c : %d\t",  c, data[c] );
        else
            printf("[%02x]: %d\t", c, data[c] );
        if(c%8==7)
            printf("\n");

に変えてやることで、正常にかつきれいに表示されるでしょう。
 
 

box

Re:ASCIIコードの文字をカウント

#4

投稿記事 by box » 18年前

> 後、配列の中身が初期化されていない

data[/url]は関数の外側にあるので、明示的な初期化は特にいりません。
仮に明示的な初期化を行なう場合は、

> int data[256]={};

ではなく(コンパイル時に「初期化子がない」のようなエラーが出ませんか?)、

 int data[256]={ 0 };

です。

管理人

Re:ASCIIコードの文字をカウント

#5

投稿記事 by 管理人 » 18年前

>data[/url]は関数の外側にあるので、明示的な初期化は特にいりません。

うあ、知りませんでした。すみません。

>ではなく(コンパイル時に「初期化子がない」のようなエラーが出ませんか?)、

エラーは出ませんし、

>int data[256]={};

これでも正常に初期化が出来ると思うのですが、間違っているのでしょうか?
/*sample1*/

#include <stdio.h>

void main(void){
	int a[5];
	printf("%d",a[0]);
}

実行結果

4214511


/*sample2*/

#include <stdio.h>

void main(void){
	int a[5]={};
	printf("%d",a[0]);
}

実行結果

0
 
 

box

Re:ASCIIコードの文字をカウント

#6

投稿記事 by box » 18年前

> 	int a[5]={};

当方の環境(Windows2000, BCC5.5.1)では
コンパイル時に「式が必要」のエラーが出ます。

ほぼすべてのコンパイラを通すには、初期化するための
値を明記する方がよさそうです。

管理人

Re:ASCIIコードの文字をカウント

#7

投稿記事 by 管理人 » 18年前

なるほど、そこはコンパイラによるのですね。
今までずっとこれで何の警告も出ないのでこちらが正しいのだと思っていました。
また人のトピで逆に勉強させてもらいました。ありがとうございますm(_ _)m

a_to_b

Re:ASCIIコードの文字をカウント

#8

投稿記事 by a_to_b » 18年前

みなさんありがとうございます!
無事表示させることが出来ました。

isprintfというのは知らなかったので、
とてもタメになりました(^_^)

閉鎖

“C言語何でも質問掲示板” へ戻る