chop.chop さんが書きました:この前の続きとなるのですが、やはり構造体のメンバ変数として、別の構造体へのポインタを指定するときの書き方に問題があるらしくコンパイル時にエラーが出まくりです。
gcc 4.8.1でコンパイルしたところ、エラーは一件も出ませんでした(273行目未修正)。
コード:
YUKI.N>gcc --version
gcc (GCC) 4.8.1
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
YUKI.N>gcc -Wall -Wextra -g3 -static -o raw9.exe raw9.c
raw9.c: In function 'putin':
raw9.c:188:19: warning: assignment from incompatible pointer type [enabled by de
fault]
(*margepri).dom=now;
^
raw9.c:205:41: warning: assignment from incompatible pointer type [enabled by de
fault]
(marge[asc]).dom=now;
^
raw9.c: In function 'joint':
raw9.c:227:12: warning: assignment from incompatible pointer type [enabled by de
fault]
now->next=(*margepri).dom;
^
raw9.c:234:13: warning: assignment from incompatible pointer type [enabled by de
fault]
now->next=(marge[i]).dom;
^
raw9.c: In function 'listmarge':
raw9.c:269:4: warning: passing argument 2 of 'putin' from incompatible pointer t
ype [enabled by default]
putin(now,&margepri,margem,asc,lastmpri,lastm);
^
raw9.c:182:6: note: expected 'struct LIST *' but argument is of type 'struct LIS
T **'
void putin(YJ *now,LIST *margepri,LIST *marge,int asc,YJ *lastmpri,YJ *lastm[26
])
^
raw9.c:273:7: warning: left-hand operand of comma expression has no effect [-Wun
used-value]
(top,&margepri,margem,lastmpri,lastm);
^
raw9.c:273:17: warning: left-hand operand of comma expression has no effect [-Wu
nused-value]
(top,&margepri,margem,lastmpri,lastm);
^
raw9.c:273:24: warning: left-hand operand of comma expression has no effect [-Wu
nused-value]
(top,&margepri,margem,lastmpri,lastm);
^
raw9.c:273:33: warning: left-hand operand of comma expression has no effect [-Wu
nused-value]
(top,&margepri,margem,lastmpri,lastm);
^
raw9.c:273:3: warning: statement with no effect [-Wunused-value]
(top,&margepri,margem,lastmpri,lastm);
^
raw9.c:242:56: warning: unused parameter 'i' [-Wunused-parameter]
void listmarge(YJ *top,LIST *margepri,LIST *margem,int i,int maxw,YJ *lastmpri,
YJ *lastm[26])
^
raw9.c: In function 'sortlist':
raw9.c:316:8: warning: unused variable 'j' [-Wunused-variable]
int i,j;
^
raw9.c: In function 'main':
raw9.c:346:11: warning: unused variable 'now' [-Wunused-variable]
YJ *top,*now;
^
raw9.c:343:14: warning: unused parameter 'argc' [-Wunused-parameter]
int main(int argc,char *argv[])
^
raw9.c: In function 'sortlist':
raw9.c:325:12: warning: 'lastmpri' may be used uninitialized in this function [-
Wmaybe-uninitialized]
listmarge(top,&margepri,marge,i,maxw,lastmpri,lastm);
^
YUKI.N>
chop.chop さんが書きました:またある関数内で宣言したポインタの配列を、他の関数に参照渡しすることもうまくできません…
具体的に、どういうことがしたいのでしょうか?
[hr]
実行すると不自然に多くの出力がなされてしまいますが、とりあえずインデントを整え、gccの警告を全て潰してみました。
まだ解読はしていないです。
コード:
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
#include<time.h>
//構造体YJの定義
typedef struct yj
{
int numdot;
int lastdot;
int nextdot;
char word[256];
struct yj *next;
}YJ;
//領域確保用の関数
YJ *newyj()
{
YJ *p;
p=(YJ *)malloc(sizeof(YJ));
if(p==NULL)
{
fputs("malloc failedn\n",stderr);
exit(1);
}
else
{
return p;
}
}
//この構造体を配列にしてマージソートに使いたい
typedef struct list
{
//struct YJ *dom;//すでに上で定義した構造体型のポインタ
YJ *dom;//すでに上で定義した構造体型のポインタ
}LIST;
//ファイルの中身からリストを作るだけの関数
YJ *makelist(char filename[256])
{
FILE *fp;
fp=fopen(filename,"r");//ファイル開く
//エラー処理
if(fp==NULL)
{
printf("file open failed(%s)\n",filename);
}
int c;//ファイルから読み取った文字を格納
int i=0;
YJ *top,*now,*new;
//入力順にリスト作成開始
new=newyj();
now=new;
top=now;
now->numdot=0;//初期化
now->lastdot=-1;//文字列の最初の1つ前ににdotがあると仮定
while((c=fgetc(fp))!=EOF)
{
if(c!='\n')
{
if(c=='.')
{
(now->numdot)++;
}
now->word[i]=c;
i++;
}
else if(c=='\n')
{
now->word[i]='\0';
new=newyj();//新しい領域確保
now->next=new;//これにより、現在のnowの指す領域のnextは上で確保した領域となる
now=new;//次のループに向け、nowを上で確保した領域に再指定
i=0;
now->numdot=0;//初期化
now->lastdot=-1;//最初の1つ前にdotがあると仮定
}
}
now->next=NULL;
fclose(fp);
return top;
}
//メンバをNULLに初期化する関数
void resetdom(LIST *margepri,LIST *marge)
{
int i;
(*margepri).dom=NULL;
for(i=0;i<26;i++)
{
(marge[i]).dom=NULL;
}
}
//行ごとにいくつのdotがあるかを見つける関数
void findmaxdot(YJ *top,int *maxdot)
{
YJ *now;
now=top;
while(now->next!=NULL)
{
if(*maxdot<(now->numdot))
{
*maxdot=now->numdot;
}
now=now->next;
}
printf("Maxdot:%d\n",*maxdot);
}
//現在の区画中の最大文字数を特定する,次のdot特定
void findmaxword(YJ *top,int *maxw,int i)
{
YJ *now;
now=top;
int l;
int maxtemp;
while(now->next!=NULL)
{
maxtemp=0;
l=(now->lastdot)+1;
while(1)
{
printf("%c",now->word[l]);
//行の区画数が不足の時
if((now->numdot)<i)
{
break;
}
//行の端ordotまで読んだ時
if(((now->word[l])=='\0')||((now->word[l])=='.'))
{
now->nextdot=l;//現在の区画の終了の添字
break;
}
else
{
maxtemp++;
l++;
}
}
printf("@");
//大小比較
if(maxtemp>(*maxw))
{
(*maxw)=maxtemp;
}
now=now->next;
printf("maxw:%d\n",*maxw);
}
}
//lastdot置き換え
void setlastdot(YJ *top,int i)
{
YJ *now;
now=top;
while(now->next!=NULL)
{
if((now->numdot)<i)
{
//区画数が足りない場合はそのまま
}
else
{
now->lastdot=now->nextdot;//置き換え
}
now=now->next;
}
}
void putin(YJ *now,LIST *margepri,LIST *marge,int asc,YJ *lastmpri,YJ *lastm[26])
{ //文字が足りないとき
if(asc=='@')
{
if((*margepri).dom==NULL)//何もリストが連結されていないとき
{
(*margepri).dom=now;
lastmpri=now;
lastmpri->next=NULL;
}
else
{
lastmpri->next=now;
lastmpri=now;
lastmpri->next=NULL;
}
}//アルファベットの時
else
{
asc=asc-97;//これでascは0~25になる
if((marge[asc]).dom==NULL)//何もリストが連結されていないとき
{
(marge[asc]).dom=now;
lastm[asc]=now;
lastm[asc]->next=NULL;
}
else
{
lastm[asc]->next=now;
lastm[asc]=now;
lastm[asc]->next=NULL;
}
}
}
void joint(YJ *top,LIST *margepri,LIST *marge,YJ *lastmpri,YJ *lastm[26])
{
int i;
YJ *now;
now=top;
if(((*margepri).dom)!=NULL)//文字なしのところの処理
{
now->next=(*margepri).dom;
now=lastmpri;
}
for(i=0;i<=25;i++)
{
if(((marge[i]).dom)!=NULL)
{
now->next=(marge[i]).dom;
now=lastm[i];
}
}
}
void listmarge(YJ *top,LIST *margepri,LIST *margem,int i,int maxw,YJ *lastmpri,YJ *lastm[26])
{
YJ *now,*temp;
int j;
int asc;
int l;
(void)i; // 未使用の警告避け
for(j=maxw;j>=1;j--)
{
now=top;
l=(now->lastdot)+j;
while(now->next!=NULL)
{ //文字が足りない時
if(l>=(now->nextdot))
{
asc='@';
}//大文字
else if((65<=(now->word[l]))&&((now->word[l])<=90))
{
asc=(now->word[l])+32;
}//小文字
else if((97<=(now->word[l]))&&((now->word[l])<=122))
{
asc=now->word[l];
}
//marge配列に格納
temp=now->next;//退避
//putin(now,&margepri,margem,asc,lastmpri,lastm);
putin(now,margepri,margem,asc,lastmpri,lastm);
now=temp;//退避したやつ戻す
}
//この時点ですべての行はバケットソート用の配列にリストとして格納されているため、ここからまたtopから辿れるように戻す
//joint(top,&margepri,margem,lastmpri,lastm);
joint(top,margepri,margem,lastmpri,lastm);
//デバッグ
printf("\n\n");
now=top;
while(now->next!=NULL)
{
printf("%d,%s\n",now->numdot,now->word);
now=now->next;
}
}
}
//ソート用の関数
void sortlist(YJ *top)
{
YJ *now;
//とりあえずデバッグのために表示
now=top;
while(now->next!=NULL)
{
printf("%d,%s\n",now->numdot,now->word);
now=now->next;
}
//ソート用のリスト
LIST margepri;//@文字の時に収納される配列(@の時は文字不足)
YJ *lastmpri;//ソート用のリストの最後の要素を指すポインタ
LIST marge[26];//アルファベット用
YJ *lastm[26];//ソート用のリストの最後の要素を指すポインタ(アルファベット用)
//構造体のメンバのdomをNULLに初期化
resetdom(&margepri,marge);
lastmpri=NULL; // 未初期化の警告避け
//各行の中のdotの数を見つける
int maxdot=0;
findmaxdot(top,&maxdot);
printf("\n");
//ここからdotで区切られた文字列ごとにソートをかけていく
int i,j;
int maxw=0;//現在の区画の中で最大の文字数
for(i=maxdot;i>=0;i--)
{
now=top;
//現在の区画でどの行の文字列が一番多いのかを特定,次のdot特定
findmaxword(top,&maxw,i);
//入れ替え
listmarge(top,&margepri,marge,i,maxw,lastmpri,lastm);
//置き換え
setlastdot(top,i);
printf("\n\n");
}
(void)j; // 未使用の警告避け
}
int main(int argc,char *argv[])
{
YJ *top,*now;
(void)argc; // 未使用の警告避け
(void)now; // 未使用の警告避け
top=makelist(argv[1]);
if(top==NULL)
{
return -1;
}
sortlist(top);
return 0;
}