• ベストアンサー

エラーの意味

このプログラムは、三番目のコマンドライン引数に、 watch が入力されると、画面に文字表示されるはずですが、 おそらく if ( argv [3] == 'a' ) putchar ( c ) のところで、エラーが出ます。 文字列定数は 、1 文字か 2 文字でなければならない ( 関数 main ( int,char * * ) ) ' int ' 型は 、' char * ' 型に変換できない ( 関数 main ( int,char * * ) ) このエラーの意味が解らないのですが、何を伝えたいのか解説をお願いします。 int main(int argc,char *argv[]) { FILE *fp ,*fp1; int c; fp=fopen(argv[1],"r"); if(argv[1]==NULL){ printf("no open"); exit(1); } fp1=fopen(argv[2],"w"); if(argv[2]==NULL){ printf("no open"); exit(1); } while ( ( c=fgetc ( fp ) ) !=EOF ) { fputc ( c , fp1 ) ; if ( argv[3] == ' watch ' ) putchar ( c ) ; }

質問者が選んだベストアンサー

  • ベストアンサー
  • chie65536
  • ベストアンサー率41% (2512/6032)
回答No.3

>文字列定数は 、1 文字か 2 文字でなければならない ( 関数 main ( int,char * * ) ) 「'」で括られた文字は、文字列ではなく、intの整数です。 char c; c='a'; は char c; c=0x61; と同等です。同様に int i; i='あ'; は int i; i=0x82a0; と同等です。 その為「'」で括られた中には、1文字(半角1文字)か2文字(全角1文字)しか書けません。 つまり if ( argv[3] == 'watch' ) は 「文字列定数は 、1 文字か 2 文字でなければならない」に違反するのでエラーになります。 >' int ' 型は 、' char * ' 型に変換できない ( 関数 main ( int,char * * ) ) 「argv[3]」は「char *型」です。一方「'~'」は上記で書いた通り「int型」です。 コンパイラは「char *型」と「int型」を比較するよう指示されたので、int型をchar *型に昇格しようとしました。でも「'int' 型は 、'char *' 型に変換できない」のでエラーになります。 質問者さんがやろうとした比較 >if ( argv[3] == 'watch' ) は if ( "abcdef" == 0x7761 ) と同等です。こう書けば「明らかに間違ってる」のが判りますね? では、比較する定数を以下のように「'」ではなく「"」で括ればと思うでしょうが、これも間違いです。 if ( argv[3] == "watch" ) この比較は「argv[3]が存在するメモリのアドレス」と「文字列定数"watch"が置かれているメモリのアドレス」を比較するので「常に等しくない」と評価されます。例えargv[3]に「watch」が入っていても「等しくない」のです。 なお、蛇足ですが、 if ( "watch" == "watch" ) は「等しくないか、等しいか、判らない」です。右辺の文字列定数"watch"が置かれているメモリのアドレスと、左辺の文字列定数"watch"が置かれているメモリのアドレスは、同じアドレスになるか違うアドレスになるか、厳密には決まっていません。 なぜなら「内容が同一の複数の文字列定数は、実体を1つにまとめてメモリ消費を抑えても良いし、それぞれ別々の実体を持っても良い」と言う事になっているからです。 質問者さんがやろうとした比較を踏襲して修正すると if (( argv[3][0] == 'w' ) && ( argv[3][1] == 'a' ) && ( argv[3][2] == 't' ) && ( argv[3][3] == 'c' ) && ( argv[3][4] == 'h' ) && ( argv[3][5] == '\0' )) となります。 しかし、普通はこんな書き方はせず、 if (strcmp(argv[3],"watch") == 0) と書きます。 質問者さんは「文字定数」と「文字列定数」が区別できてません。 また、argvが「文字列へのポインタが集まった配列である」と言う事も理解できてません。

startover
質問者

お礼

すばやい回答ありがとうございます。 すごく詳しい回答ありがとうございます! よく解りました! 本当にありがとうございました!

その他の回答 (3)

回答No.4

直接ご質問の内容ではないのですが…… fp=fopen(argv[1],"r"); if(argv[1]==NULL){ ファイルオープンの失敗は、if(fp == NULL) で判定すべきです。 fopen() は、ファイルオープンに失敗したときに NULL を返すので。 (argv[1] は、元のコマンドライン引数の内容をポイントしています) また、argv[1] や argv[2] や argv[3] が必ず有効な文字列をポイントしている保証はないので、argc の値をチェックした方が安全ではあります。 ちなみに、argv[0] は、必ず有効な文字列をポイントしていることになっています。

startover
質問者

お礼

すばやい回答ありがとうございます。 ファイル処理の本当に、作法勉強になります。 どうもありがとうございました!

  • ham_kamo
  • ベストアンサー率55% (659/1197)
回答No.2

No.1です。初歩的なミスを犯しました。 if ( strcmp(argv[3],"watch") = 0 ) ではなく if ( strcmp(argv[3],"watch") == 0 ) です。

  • ham_kamo
  • ベストアンサー率55% (659/1197)
回答No.1

if ( argv[3] == ' watch ' ) が誤りです。 if ( strcmp(argv[3],"watch") = 0 ) とすればいいと思います。 ・文字列は''でなく""で囲みます。 ・そもそもCには文字列型というのはありません。文字列はcharの配列として扱われます。 ・そのため、文字列の結合や比較などは、上記のような文字列操作関数を使う必要があります。 C++になると、またちょっと変わってきますが。 あとお節介ですが、 ・このあとちゃんとfclose()ややっていますか? ・エラーメッセージはprintf()でなくfprintf(stderr,"…"))で標準エラー出力に出した方がよいでしょう

startover
質問者

お礼

すばやい回答ありがとうありがとうございます。 fclose( )忘れてました~ すごく解りやすい解説をありがとうございました!

関連するQ&A

  • エラーが出ます

    12,51,13,123,133,551,… というコンマで区切られているファイルを読み込みたいです。数字は100文字です。どう書けば全部読み込めるでしょうか? よろしくお願いします。 int main(int argc,char *argv[ ]){ int line; int i; FILE *fp; fp = (argc > 1)? fopen(argv[1],"r"): stdin; if(fp==NULL){ perror("fopen"); exit(0); }   while(fscanf(fp,"%d",&line) != EOF){ printf("%d\n") } if(argc>1){ fclose(fp);   }

  • 任意のファイルを別のファイルにコピーするプログラム。

    コマンドラインからコピー元、コピー先ファイル名を指定してファイルをコピーするプログラムなんですが… #include <stdio.h> #include <stdlib.h> main(int argc, char *argv[]) { FILE *fp; if ((fp = fopen(argv[0],"r") == NULL){ printf("ファイル%sが存在しません。\n",argv[0]);exit(-1); } if ((fp = fopen(argv[1],"w") == NULL){ printf("ファイル%sがコピーできません。\n",argv[1]);exit(-1); } fclose(fp); } どこか間違っているところがあるでしょうか? ありましたら詳しく教えてもらえると幸いです。 少し自信がないのでわかる方はよろしくおねがいします。

  • エラーがでてしまいます

    以下のプログラムなのですが、引数を与えると下のようなエラーになります。 #include<stdio.h> #include<stdlib.h> int main(int argc, char** argv) { FILE *in ,*out; unsigned char ch; if(argc != 3) { printf("入力エラーです。\n"); exit(1); } if((in = fopen(argv[1],"rb")) == NULL) { printf("入力ファイルが開けません。\n"); exit(1); } if((out = fopen(argv[2],"rb")) == NULL) { printf("出力ファイルが開けません。\n"); exit(1); } while(!feof(in)) { ch = fgetc(in); if(!feof(in)) fputc(~ch,out); } fclose(in); fclose(out); return 0 ; } tyobi@tyobi-laptop:~$ gcc test.c diary copy diary: file not recognized: File format not recognized collect2: ld はステータス 1 で終了しました どうしたらよいのでしょうか?

  • 探索アルゴリズム

    テキストファイルを読み込んで、該当する文字列を含む行を表示するというプログラムを作りたいのです。ファイルを読み込むことはできるのですが、該当する文字列を含む行を表示するやり方がわかりません。どなたか助けてもらえないでしょうか? 一応私が作ってみたプログラムはこんな感じになったんですけど・・・ #include <stdio.h> #include <stdlib.h> int main(int argc, char *argv[]) {  FILE *fp;  char ch;  if( argc != 3)  {  printf(" 使用法 : <プログラム名> <ファイル名> <文字> \n");  return -1;  }  if((fp = fopen(argv[1],"r")) == NULL)  {  printf("ファイルを開くことができません\n");  return -1;  }  while(( ch = fgetc(fp)) != EOF)  if(ch == *argv[2])  {  printf("%cが見つかりました\n",ch);  break;  }  fclose(fp);  return 0; }

  • 文章から改行を削除して表示する

    #include<stdio.h> #include<stdlib.h> int main(int argc, char *argv[]) { FILE *fp; char row[124]; int c; if( (fp=fopen(argv[1],"r")) == NULL){ fprintf(stderr,"eror\n"); exit(1); }else{ while(fgets( row , sizeof(row) , fp)!=NULL){ printf("%s",row); } fclose (fp); } } というコードでtex.txtという文章ファイルから改行を削除した結果を表示したかったのですが、結果としてオリジナルとまったく同じ文が出てきます。fgetsで改行はふくまれないようにしたつもりなのですが、何故でしょう?解説お願いします。 text.txt: abcdefg hijklmn opqrstuvwxyz

  • コマンドラインによるファイル名指定

    #include<stdio.h> #include<stdlib.h> int main(int argc,char *argv[]) { FILE *fp,*fpc; int i=0; char line[1000]; fp = fopen("test.txt","r"); if(fp == NULL) { printf("File not found.\n"); exit(1);  }  fpc = fopen(argv[1],"w"); if(fpc==NULL){ fprintf(stdout,"Can not open file.\n"); exit(1); } while(fgets(line[i],1000,fp)!=NULL){ i++; } for(i=3;i<0;i--){ fprintf(fpc,"%s",line[i]); } fclose(fp); fclose(fpc); return 0; } コマンドラインでファイル名を指定し、そのファイルに、test.txt(4行の文字列)の内容を各行を逆順に書き出すプログラムですが、上手くいきません。ご指摘を願いします。

  • おしえて

    #include <stdio.h> #include <stdlib.h> int a[30000][6]; int main(int argc, char *argv[]) { FILE *fp; int c,n,i,j; if ((fp = fopen(argv[1], "r")) == NULL) { printf("File Open Error.\n"); exit(1); } for(i=0;i<30000;i++){ for(j=0;j<6;j++){ c = fscanf(fp, "%d", &n); if (c) { a[i][j]=c; printf("%d ",a[i][j]); } } printf("\n"); } fclose(fp); return 0; } このプログラムを書きましたna.txtのファイルが以下のようなとき 1 2 3 4 5 6 3 4 5 6 7 8 のとき先頭の1しか配列に格納できません。どうしても順番にa[0][0~5]=1~6と入れたいです。どうしてもわかりません。おしえてください!!

  • C言語、ファイル操作、fgets()について

    次のプログラムは入力された行を読み込み、コマンドラインで指定されたファイルに書き込みます。 空白行が入力されたら、入力の終了とみなしてファイルを閉じます。続いてファイルを入力用に開き、 fgets()を使ってファイルの内容を表示するものです。 (ソースコードが長くてすみません) #include <stdio.h> #include <stdlib.h> #include <string.h> int main(int argc, char *argv[]) { FILE *fp; char str[80]; /* コマンドライン引数を検査する */ if(argc!=2) { printf("ファイル名を指定してください\n"); exit(1); } /* 出力用にファイルを開く */ if((fp = fopen(argv[1], "w"))==NULL) { printf("ファイルを開くことができません\n"); exit(1); } printf("終了するには空白行を入力してください\n"); do { printf(": "); gets(str); strcat(str, "\n"); /* 改行を追加する */ if(*str != '\n') fputs(str, fp); } while(*str != '\n'); fclose(fp); /* 入力用にファイルを開く */ if((fp = fopen(argv[1], "r"))==NULL) { printf("ファイルを開くことができません\n"); exit(1); } /* ファイルを読み込み直す */ do { fgets(str, 79, fp); if(!feof(fp)) printf(str); } while(!feof(fp)); fclose(fp); return 0; } 【質問】fgets()内のint型の数値「79」がどうして79なのかが分かりません。     80でも良いような気がするのですが・・・

  • C言語の質問です

    下記のプログラムはテキストファイルを読み込み、AからZまでの文字(小文字、大文字は区別しない)がそれぞれ何回 現れたかを数えるプログラムです。 #include <stdio.h> #include <stdlib.h> #include <ctype.h> int count[26]; int main(int argc, char *argv[]) { FILE *fp; char ch; int i; /* ファイル名の指定を調べる */ if(argc!=2) { printf("ファイル名の指定がありません\n"); exit(1); } if((fp = fopen(argv[1], "r"))==NULL) { printf("ファイルを開くことができません\n"); exit(1); } while((ch=fgetc(fp))!=EOF) { ch = toupper(ch); if(ch>='A' && ch<='Z') count[ch-'A']++; } for(i=0; i<26; i++) printf("%c は %d 回出現\n", i+'A', count[i]); fclose(fp); return 0; } 1)int count[26]; で、なぜ26なのかが分かりません。 2)count[ch-'A']++; はどういう動作をするのか詳しく教えてほしいです。 3)よって、for文がどういう動作で表示しているのかが分かりません。 未熟者の私ですが、どなたか教えていただけないでしょうか?

  • ファイル

    AからZまでの文字が何回出力されるか数えるプログラムなのですが、うまく出力されません。 どこを変えればよろしいでしょうか。 #include<stdio.h> #include<stdlib.h> #include<ctype.h> int count[26]; int main(void) { char str[100] = "xyzYZZ\n"; FILE *fp; char *p; int i; char ch; if((fp = fopen("myfile","w")) == NULL){ printf("ファイルを開くことが出来ません"); exit(1); } p = str; while(*p){ if(fputc (*p,fp) == EOF){ printf("ファイル書き込みエラー"); exit(1); } p++; } fclose(fp); if((fp = fopen ("myfile","r")) == NULL){ printf("ファイルを開くことが出来ません"); exit(1); } while((ch == fgetc(fp)) != EOF){ ch = toupper(ch); if( ch >= 'A' && ch <='Z' ) count[ch - 'A']++ ; } for( i=0 ; i<26 ; i++) printf("%c は %d 回出現\n",i + 'A', count[i]); fclose(fp); return 0; }