質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

3回答

1132閲覧

C言語 別ファイルを配列に読み込んでコマンドで操作(reallocの使用方法)

nekoatsume

総合スコア7

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

1クリップ

投稿2020/05/24 15:30

C言語初心者です。
別ファイルを配列に読み込んで、複数のコマンドで操作できるような下記のコードを書きました。
下記のコマンドで'a'( カーソル行の後ろに1行挿入(カーソル移動させる))について、
元々256の1行あたりの最大文字数だったのを、
1024まで増やすことができるようreallocを使って改造したいです。
文字数MOJIを1024と定義しreallocして文字数を増やしたいのですが、
下記のコンパイルエラーがでます。
演算子の不適切な利用で起こるエラーのようですが、どうしたらコンパイルが通るのか理解できず
ご指摘いただけたら幸いです。

<エラー内容>コマンドaの箇所
invalid operands to binary(have 'int' and 'int*')
moji=realloc(moji,sizeof(int)(MOJI ++moji));

C

1#include <stdio.h> 2#include <stdlib.h> 3#include <unistd.h> 4#include <string.h> 5#include <ctype.h> 6 7#define GYO 200 //1ファイルの最大行数 8#define MOJI 1024 //1行の最大文字数 9#define LINE line+1 10 11int kansu(char* str,FILE* fp); 12 13int main(int argc,char* argv[]) 14{ 15 16FILE* fp; 17int* moji; 18char str[GYO][MOJI]; 19moji=malloc(sizeof(int)*MOJI); 20char retsu[128]; 21int i=0; 22int line=0;//現在の行番号 23int gyo; 24int k; 25line=malloc(sizeof(int)*LINE); 26line=malloc(sizeof(int)*(LINE* ++line)); 27 28 29   if(argc==2){ 30    if((fp=fopen(argv[1],"r"))==NULL){ 31    printf("ファイルが開けませんでした\n"); 32    exit(EXIT_FAILURE); 33    } 34   } 35else{ 36printf("引数の値が不正です\n"); 37exit(EXIT_FAILURE); 38} 39//strにファイルの内容読込み 40while(fgets(str[i],MOJI,fp)!=NULL){ 41//ファイルの行数チェック 42  if(i>GYO){ 43   printf("ファイルの長さが[%d]を超えました",GYO); 44   break; 45  } 46 47  if(strlen(str[i])==255){ 48   if(kansu(str[i],fp)){ 49    exit(EXIT_FAILURE); 50  } 51    printf("strlen=[%ld]\n",strlen(str[i])); 52  } 53 54    printf("%d:%s",LINE,str[line]); 55    printf("%ld\n",strlen(str[line])); 56    line++; 57    i++; 58  } 59 60 61   line--; 62    int line_max=line;//ファイル全体の行数 63   while(1){ 64 printf("コマンドを入力してください:"); 65    fgets(retsu,sizeof(retsu),stdin); 66   //大文字も小文字も対応する処理 67    for(k=0;k<strlen(retsu);k++){ 68    retsu[k]=tolower(retsu[k]); 69    } 70    //nコマンドのため 71    gyo=atoi(retsu); 72    gyo--; 73 //各コマンドの処理 74    if(strchr(retsu,'o')){ 75      for(int i=0;i<line_max;i++){ 76    if(i==line){ 77    printf("*%d:%s\n",i+1,str[i]); 78    }else{ 79    printf("%d:%s\n",i+1,str[i]); 80      } 81    } 82    printf("line:%d\n",LINE); 83    printf("line_max:%d\n",line_max+1); 84 85    }else if(strchr(retsu,'d')){ 86        if(line==0){ 87        strcpy(str[line],""); 88        printf("配列削除しました\n"); 89    }else if (line_max==line){ 90        strcpy(str[line],""); 91        line--; 92        line_max--; 93 94    }else{ 95       for(i=line;0<=(line_max-i);i++){ 96       strcpy(str[i],str[i+1]); 97       } 98      line_max--; 99    } 100 101       printf("*%d:%s\n",LINE,str[line]); 102 103   }else if(strchr(retsu,'r')){ 104       if(line<0){ 105       printf("文字列が入っていません\n"); 106       continue; 107   } 108       printf("Enter sentence:"); 109       fgets(str[line],MOJI,stdin); 110       printf("%d:%s\n",LINE,str[line]); 111       continue; 112 113   }else if(strchr(retsu,'a')){ 114   if(line<0){ 115    printf("文字列が入っていません\n"); 116    continue; 117   } 118   for(int i=line_max; i>=line; i--){ 119     strcpy(str[i+1],str[i]); 120   } 121     line_max++; 122     line++; 123     fgets(str[line],sizeof(str[line]),stdin); 124 moji=realloc(moji,sizeof(int)*(MOJI* ++moji)); 125     printf("*%d:%s\n",LINE,str[line]); 126     continue; 127 128   }else if(strchr(retsu,'i')){ 129     for(int i=line_max;i>=line;i--){ 130     strcpy(str[i+1],str[i]); 131   } 132      line_max++; 133    fgets(str[line],sizeof(str[line]),stdin); 134    printf("*%d:%s\n",LINE,str[line]); 135 136   }else if(strchr(retsu,'p')){ 137       if(line<1){ 138       printf("ファイルの先頭です\n"); 139       continue; 140   } 141       line--; 142       printf("*%d:%s\n",LINE,str[line]); 143 144   }else if(strchr(retsu,'n')){ 145   if(line>line_max){ 146       printf("最端行数を超えました\n"); 147       line=line_max; 148   } 149       line++; 150       printf("*%d:%s\n",LINE,str[line]); 151       continue; 152 153   }else if(strchr(retsu,'s')){ 154    int p=line-10; 155      if(p<1){ 156       p=1; 157   } 158    int n=line+10; 159    if(n>line_max){ 160    n=line_max; 161   } 162   for(i=p;i<=line;i++){ 163      printf("%d:%s\n",i,str[i-1]); 164   } 165      printf("*%d:%s\n",LINE,str[line]); 166   for(i=line+1;i<n+1;i++){ 167      printf("%d:%s\n",i+1,str[i]); 168   } 169   continue; 170 171   }else if(strchr(retsu,'f')){ 172char z[MOJI]; 173if(line-1<0) 174{ 175printf("入替えできません\n"); 176continue; 177} 178strcpy(z,str[line]); 179strcpy(str[line],str[line-1]); 180strcpy(str[line-1],z); 181printf("%d:%s\n",LINE,str[line]); 182continue; 183 184 185 186  }else if(strchr(retsu,'b')){ 187    char y[MOJI]; 188    if(line-1<0) 189  { 190    printf("入替えできません\n"); 191    continue; 192  } 193    strcpy(y,str[line]); 194    strcpy(str[line],str[line+1]); 195    strcpy(str[line+1],y); 196    printf("%d:%s\n",LINE,str[line]); 197    continue; 198 199   }else if (strchr(retsu, 'v')) { 200  char fname[128]; 201  char c2[5]; 202  FILE* wfp; 203  printf("file name is [%s] ?:[y or n]: ", argv[1]); 204    205  fgets(c2, sizeof(c2), stdin); 206 207  if (strchr(c2, 'y')) { 208    strcpy(fname, argv[1]); 209  } else if (strchr(c2, 'n')) { 210    printf("Enter file name:"); 211  fgets(fname,sizeof(fname),stdin); 212  } else if(c2[0] == '\n') { 213    continue; 214  } else { 215   printf("Command Error.[%s]\n",c2); 216   continue; 217  } 218 219  if ((wfp = fopen(fname, "w")) == NULL) { 220    printf("File open Error:w\n"); 221  } 222    for (i=0; i <= line_max; i++) { 223    fprintf(wfp, "%s", str[i]); 224  } 225    fclose(wfp); 226    printf("Write Finish...\n"); 227    continue; 228 229 230  }else if(strchr(retsu,'t')){ 231   line=1; 232   printf("%d:%s\n",LINE,str[line]); 233  }else if(strchr(retsu,'l')){ 234  line=line_max; 235  printf("%d:%s\n",LINE,str[line]); 236  printf("linemax=%d\n",line_max+1); 237 238 239  }else if(strchr(retsu,'x')){ 240   printf("終了\n"); 241   break; 242  }else if(gyo<=line_max && gyo>=0){ 243   line=gyo; 244   printf("*%d:%s\n",LINE,str[line]); 245   continue; 246  }else{ 247   printf("retsu:%s\n",retsu); 248   printf("line:%d\n",line); 249   printf("コマンドが不正です\n"); 250   continue; 251  } 252 253  } 254   fclose(fp); 255   exit(EXIT_SUCCESS); 256  } 257 258 259///関数 260 261 262int kansu (char* str,FILE* fp) 263{ 264int i=254; 265int r=0; 266 267printf("str[i]==[%d]\n",(unsigned char)str[i]); 268printf("str[i]==[%c]\n",(unsigned char)str[i]); 269printf("str[i]==[0x%x]\n",(unsigned char)str[i]); 270 271  if((unsigned char)str[i]=='\n' || str[i]=='\0'){ 272     printf("改行、NULLを検知する\n"); 273     return 0; 274  } 275 276  else if((unsigned char)str[i]>=0 && (unsigned char)str[i]<=127){ 277   printf("00〜7Fに入りました\n"); 278   str[i+1]=10; 279   str[i+2]=0; 280   return 0; 281  } 282 283     284  else if((unsigned char)str[i]>=224 && (unsigned char)str[i]<=239){printf("E0〜EFに入りました\n"); 285   str[i]=10; 286   str[i+1]=0; 287   r=fseek(fp,sizeof(char)*-1,SEEK_CUR); 288    if(r){ 289      printf("seekに失敗しました\n"); 290      return -1; 291   } 292      return 0; 293   } 294   else if((unsigned char)str[i]>=128 &&(unsigned char)str[i]<=191){ 295    printf("80~8Fに入りました\n"); 296      if((unsigned char)str[i-1]>=128 &&(unsigned char)str[i-1]<=191){ 297      str[i+1]=10; 298      str[i+2]=0; 299      return 0; 300  } 301   else{ 302      str[i-1]=10; 303      str[i]=0; 304      return 0; 305      r=fseek(fp,sizeof(char)*-2,SEEK_CUR); 306      if(r){ 307           printf("seekに失敗しました\n"); 308           return -1; 309      } 310           return 0; 311    } 312 } 313 else if((unsigned char)str[i]>=224 && (unsigned char)str[i]<=239){ 314 printf("E0〜EFに入りました\n"); 315 str[i+1]=10; 316 str[i+2]=0; 317 return 0; 318 319       } 320} 321

環境はLinuxのubuntu上です。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

e-watt

2020/05/24 15:51

エラーの括弧内に「intとint*じゃん」と書いてあります。 確かにそういうコードになっているので、どこがそうなのかを見定めて、どう書けば目標が実現できるか考えましょう。
dodox86

2020/05/24 16:55

main関数の冒頭 int *moji; と宣言してmoji=malloc(sizeof(int)*MOJI);としていますが、mojiがなぜint*なのか分かりませんし、そもそもint *mojiがそのあと使われていませんが。どういう意図があったのでしょうか。
thkana

2020/05/24 22:29

実際に試したソースコードを提示して下さい。 質問のコードにはいわゆる全角空白が多数入っていて、コンパイルを通るはずがありません。 それはともかく... そもそもの話としてデータを char str[GYO][MOJI]; に格納しているのなら、malloc/reallocの出る幕ではありませんし、 #define LINE line + 1 line = malloc(sizeof(int) * LINE); line = malloc(sizeof(int) * (LINE * ++line)); この3行にどれだけ「おかしなこと」が含まれているか... これを見ただけでもあなたが自分の現在のスキルを大きく超えたことに挑戦しているとしか思えなくなります。挑戦はよいのですが、「無謀」にならないように適宜理解を積み重ねていって下さい。
guest

回答3

0

ベストアンサー

malloc/reallocの目的は、行を追加したときに200行をはみ出るから、だったと思います。
「元々256の1行あたりの最大文字数だったのを、1024まで増やす」については、MOJIの定義を1024にしたことで片付いています。

まず、strの定義ですが、charの256バイトの文字列の配列へのポインタで定義します。
strはポインタで、mallocで獲得した領域のアドレスを設定します。
初期サイズは従来どおり「1バイト×MOJI×GYO」を確保します。

C

1 int *moji; 2 char str[GYO][MOJI]; 3 moji = malloc (sizeof (int) * MOJI); 45 line = malloc (sizeof (int) * LINE); 6 line = malloc (sizeof (int) * (LINE * ++line));

C

1 //int* moji; 2 char (*str)[MOJI]; 3 str = malloc (sizeof (char) * MOJI * GYO); 45 //line = malloc (sizeof (int) * LINE); 6 //line = malloc (sizeof (int) * (LINE * ++line));

line_maxは行番号ではなく行数で扱うようにしたほうが扱いやすいです。
条件を書くときに「< line_max」の未満か「>= line_max」の以上のいずれかで表現が統一しやすくなります。

C

1 line--; 2 int line_max = line; //ファイル全体の行数

C

1 int line_max = line; //ファイル全体の行数 2 line--;

'a'の処理はfgetsで読み込んでからサイズ拡張では遅いので、サイズ拡張してから読み込むようにします。
reallocのサイズは単純に「1バイト×MOJI×line_max」にしました。

C

1 else if (strchr (retsu, 'a')) 23 line_max++; 4 line++; 5 fgets (str[line], sizeof (str[line]), stdin); 6 moji = realloc (moji, sizeof (int) * (MOJI * ++moji));

C

1 else if (strchr (retsu, 'a')) 23 line_max++; 4 line++; 5 str = realloc (str, sizeof (char) * MOJI * line_max); 6 fgets (str[line], sizeof (str[line]), stdin);

投稿2020/05/25 12:13

etsuhisa

総合スコア416

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nekoatsume

2020/05/27 07:08

無事、実装できました。教えていただきありがとうございました!
guest

0

Cのコードを書くなら、デバッグできる環境を整えましょう。
VisualStudioやEclipseなど、任意の行で実行を止め、変数の中身を確認できます。
また、1行づつ実行するようなこともできます。
そうすれば理解が早いのではないでしょうか

投稿2020/05/25 01:08

y_waiwai

総合スコア87774

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

episteme

2020/05/25 01:21

いやまだコンパイル通ってすらいないしwww
guest

0

moji=realloc(moji,sizeof(int)(MOJI ++moji));

MOJIは 1024すなわちint
moji は int*

... int と int* を足して掛けてなにがしたいのですか?

投稿2020/05/24 22:22

編集2020/05/24 23:57
episteme

総合スコア16614

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

thkana

2020/05/24 23:00

intとint*の足し算ならともかく、intとint*を掛け算しようとしたからコンパイラに怒られたのでは?
episteme

2020/05/25 01:11

ゴメン、"足して"じゃないや"掛けて"だ。(修正しました)
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問