こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

締切り済みの質問

C言語について

以下のプログラムについてです。

test.txtというファイルを読み込み、その中の異なる単語の数を求めるプログラムです。

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

#define NMAX 80
#define LMAX 5000


void count(FILE*, int);
void all_words(FILE *);

FILE *fp, *fp2;
char *fn="test.txt";
char *fn2="total word.txt";
const char *ignore="\n !?()*-;:.,_\"[]";
int main(void){

int p=0, x=0, c, l, t=0;
char word3[LMAX][NMAX];
char word1[NMAX];
char word2[NMAX];
char *tp;
char *tp2;

if((fp=fopen(fn,"r"))==NULL){
printf("Can't open '%s'.\n",fn);

return -1;
}
if((fp2=fopen(fn2,"w"))==NULL){
printf("Can't open '%s'.\n",fn2);
return -1;
}
for(c=0;c<LMAX;c++){
if(fgets(word3[c],NMAX,fp)==NULL)break;
p++;
}
for(c=0;c<p;c++){
for(x=0;x<NMAX;x++){
word1[x]=tolower(word3[c][x]);
}
tp=word1;
while((tp2=strtok(tp,ignore))!=NULL){
if(*tp2=='\''){
if(*(tp2+1)=='`'){
t=1;
}
tp2++;
}
strcpy(word2,tp2);
l=strlen(word2)-1;
if(word2[l]==('\'' && l)){
word2[l]='\0';
}
if(word2[0] =='\'' &&t==0){
if(word2[1]!='\0'){
fputs(word2+1,fp2);
fputc('\n',fp2);
}
}
else{
if(word2[0]!='\0'){
fputs(word2,fp2);
fputc('\n',fp2);
}
}
tp=NULL;
}
}
fclose(fp);
fclose(fp2);
all_words(fp2);
return 0;
}

void all_words(FILE* fp2){
char word3[NMAX];
int n=0;
if((fp2=fopen(fn2,"r"))==NULL){
printf("Can't open '%s'.\n", fn2);
return;
}
for(;;){
if(fgets(word3, NMAX,fp2)==NULL){
break;
}
n++;

}
count(fp2,n);
}

void count(FILE* fp2, int n){
int c, x, y=0;
char *m=(char *)malloc(n*NMAX);
char *xp;
char *yp;
if((fp2=fopen(fn2,"r"))==NULL){
printf("Can't open '%s'.\n", fn2);
free(m);

return;
}
for(c=0,xp=m; c<n;c++,xp+=NMAX){
fgets(xp,NMAX,fp2);
}
qsort(m,n,NMAX,(int (*)(const void*, const void*))strcmp);
c=1;
for(x=0,xp=m,yp=m+NMAX;x<n-1;xp+=NMAX,yp+=NMAX,x++){
if(strcmp(xp,yp)==0){
y++;
c++;
}
else{
c=1;
}
}
printf("KIDN OF WORD:%d\n",n-y);
free(m);
fclose(fp2);

}

このプログラムでメモリリークの原因が確保していないメモリ領域に代入しているのが原因らしいのですがどこをどう直して良いかわかりません
具体的に教えていただけないでしょうか?
よろしくお願いします

投稿日時 - 2013-06-16 21:28:28

QNo.8136922

すぐに回答ほしいです

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

-広告-
-広告-

回答(2)

ANo.3

訂正します。
strtokについては、 tp=NULL ; を見逃していました。

投稿日時 - 2013-06-17 02:29:36

ANo.2

指摘されたところを直したつもりになっているようですが、かえって悪化してます。

> while((tp2=strtok(tp,ignore))!=NULL){

しつこいようですけど、これは何を意図しているのですか?
strtokの説明は読んだのですか?

この内容だと
・word1がignoreの中の文字だけ構成される場合→ループ脱出
・それ以外→whileが無限ループになる
となります。
このstrtokで何をしたいのですか?


> if(word2[l]==('\'' && l)){

前回の指摘で変更したのでしょうけど、余計に意味がわからなくなっています。
&&演算は、0か1にしかなりません。 '\'' は0でないので、l==0のとき0,l!=0のとき1となります。つまり、このifは
if ( ( (l == 0 ) && (word2[0] == 0) ) || ( ( l != 0 ) && ( word2[l] == 1) ) ) {
と等価になります。' かどうかはまったく無関係です。
この判定は何を意図しているのですか?

> count(fp2,n);

前回書いたのは、fcloseするな、って意味じゃありません。
count関数で
if((fp2=fopen(fn2,"r"))==NULL){
と新たにfopenしているから、fp2を渡す意味が無い、と言っているのです。

渡したfp2を有効に使いたいなら、fopenせずに、fseekで先頭に戻して読み直す

cont関数内でfopenするなら、
void count(int n){
FILE *fp2;
と、nだけ渡して、fp2はローカル変数にすればいい。

現在のプログラムでは
void count(FILE * fpx , int n){
FILE *fp2;
と書いたのと同じ。fpxがまったく使われていない。

ということです。


おなじことは、all_wordでも言えます。

投稿日時 - 2013-06-17 02:07:33

-広告-
-広告-

あなたにオススメの質問

-広告-
-広告-