C言語のコピー元ファイルとコピー先ファイルを指定してファイルをコピーするプログラム

このQ&Aのポイント
  • 下記のプログラムはコマンドラインからコピー元ファイルとコピー先ファイルを指定し、コピーするプログラムです。
  • ファイルをコピーしてタブ文字を適切な数のスペースに置き換える処理を行います。
  • コピー元ファイルを開き、コピー先ファイルを作成し、ファイルをコピーします。タブ文字が出現した場合は、適切な数のスペースに置き換えます。
回答を見る
  • ベストアンサー

C言語の質問です

下記のプログラムはコマンドラインからコピー元ファイルとコピー先ファイルを指定し、コピーするプログラムです。 (コピーの際にタブ文字を適切な数のスペースに置き換えます) /* ファイルをコピーしてタブを削除する */ #include <stdio.h> #include <stdlib.h> #include <string.h> int main(int argc, char *argv[]) { FILE *from, *to; char ch; int tab, count; /* コマンドライン引数の数が適切かどうか確認する */ if(argc!=3) { printf("使用法: <プログラム名> <コピー元> <コピー先>\n"); exit(1); } /* コピー元ファイルを開く */ if((from = fopen(argv[1], "r"))==NULL) { printf("コピー元ファイルを開くことができません\n"); exit(1); } /* コピー先ファイルを開く */ if((to = fopen(argv[2], "w"))==NULL) { printf("コピー先ファイルを開くことができません\n"); exit(1); } /* ファイルをコピーする */ count = 0; while(!feof(from)) { ch = fgetc(from); if(ch=='\t') { for(tab = count; tab<8; tab++) fputc(' ', to); count = 0; } else { if(!feof(from)) fputc(ch, to); count++; if(count==8 || ch=='\n') count = 0; } } fclose(from); fclose(to); return 0; } 【質問】 「ファイルをコピーする」部分のif文のelseブロック部分が何を行っているのか分かりません。 ひとつひとつの動作は分かるのですが、全体的に何をしようとしているのか分かりません! 教えていただけないでしょうか?

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

  • ベストアンサー
noname#58357
noname#58357
回答No.2

ちなみに今回のは、tabを8に設定ていて、fromファイルが、 abc\tdef\tghi\njkl\tmno なら、toファイルは、 012345670123456701234567 <-tab位置 abc def ghi   <-toファイ1行目 jkl mno <-toファイ2行目

Guchiken
質問者

お礼

回答ありがとうございます! タブが半角8文字分とするとき、タブが開始する位置(カーソルが止まる位置)を過ぎて、文字がある場合に、タブが8文字分未満になるから、その途中の位置を知るために、count++; して、それを、for文で初期値として与える。 こういうことなんですね? どの位置からスペースに置換してよいか知るために行の桁位置を0から7としていたんですね! 回答がとても分かりやすく、理解できました。勉強になります! 回答ありがとうございました。

その他の回答 (1)

noname#58357
noname#58357
回答No.1

else { if(!feof(from)) fputc(ch, to); count++; if(count==8 || ch=='\n') count = 0; } で、 if(!feof(from)) fputc(ch, to); は、fromのデータをtoに書き込んでいます。 "if(!feof(from)) "が成立しない場合は、 ファイルの最後なので、何もしません。 count++; if(count==8 || ch=='\n') count = 0; は、tabの処理のためです。 1行中の位置を 0123456701234567--- であらわわし、0-7のどれにあたるかを"count"により 示しています。 つまり、1行中の10番目なら、count=1です。 '\n'は改行なので、行のはじめ、つまり0となります。

関連するQ&A

  • 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文がどういう動作で表示しているのかが分かりません。 未熟者の私ですが、どなたか教えていただけないでしょうか?

  • ちょっとした疑問なんですが・・・(C言語)

    何度も質問してごめんなさい! ちょっとした疑問なんですが、下記のプログラム中の、 while(!feof(in)) { ch = fgetc(in); if(!feof(in)) fputc(~ch, out); } のコードで、「while(!feof(in))」でストリーム「in」結び付けられているファイルの終わりに達していれば繰り返し処理を終えるのは分かるのですが、 なぜ、インクリメントも無くファイルの終わりまで文字を調べ進めることができるのでしょうか? 未熟者の私ですが教えて頂けないでしょうか? 【プログラム例】 #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], "wb"))==NULL) { printf("出力ファイルを開くことができません\n"); exit(1); } while(!feof(in)) { ch = fgetc(in); if(!feof(in)) fputc(~ch, out); } fclose(in); fclose(out); return 0; }

  • ファイル入出力について

    次のようなプログラムを作りました。 コマンドラインから二つのファイルの名前を読み取り、最初の引数のファイルを2番目の引数のファイルにコピーするプログラムです。 質問は下のプログラムのコメント /*この行が質問です*/ の所です。 //ファイルをコピーする の部分の始めに while(!feof(from)) という条件を書いているため、/*この行が質問です*/ の行は不要であると思いましたが、実際にこの一行をのぞいてコンパイルして実行したところ、日本語が文字化けしてコピーされてしまいました。その後、この行を追加してコンパイルして実行すると文字化けもなく実行できました。 なぜこの行が必要なのでしょうか。 よろしくお願いします。 //ファイルコピー #include<stdio.h> #include<stdlib.h> int main(int argc, char *argv[]) {   FILE *from, *to;   char ch;   //引数の数の確認   if (argc != 3) {     printf("引数の数が違います");     exit(1);   }   //コピー元ファイルを開く   if ((from = fopen(argv[1],"r")) == NULL ) {     printf("コピー元ファイルオープンエラー");     exit(1);   }   //コピー先ファイルを開く   if ((to = fopen(argv[2],"w") )== NULL ) {     printf("コピー先ファイルオープンエラー");     exit(1);   }   //ファイルをコピーする   while (!feof(from)) {     ch = fgetc(from);     if(ferror(from)) {       printf("コピー元ファイル読み込みエラー");       exit(1);     }     if (!feof(from))       /*この行が質問です*/       fputc(ch,to);     if (ferror(to)) {       printf("コピー先ファイル書き込みエラー");       exit(1);     }   }   if (fclose(from) == EOF) {     printf("コピー元ファイルクローズエラー");     exit(1);   }   if (fclose(to) == EOF) {     printf("コピー先ファイルクローズエラー");     exit(1);   }   return 0; }

  • C言語 

    #include <stdio.h> int main(void) { int ch; int count = 1; while( (ch = getchar()) != EOF) { if(ch == '\n') count++; } printf("行数は%dです。", count); return(0); } このコードの if(ch == '\n') count++; の部分がわかりません。 aを入力したとしてchにaが入っても、a=='\n'にはならないと思うのですが、実行して見ると行数がカウントされます。 (ch=='\n')というのはchと改行が同じなら行数を1増やすと言う事になると思うのですがよくわかりません。 教えてくださいm(_ _ )m

  • C言語について

    以下のプログラムについてです。 test.txtというファイルを読み込み、その中の異なる単語の数を求めるプログラムです。 #include<stdio.h> #include<stdlib.h> #include<string.h> #include<ctype.h> #include<stddef.h> #define NMAX 80 #define LMAX 5000 void count(FILE*, int); void all_words(FILE *); FILE *fp, *fp2; char *fn="alice.txt"; char *fn2="total word.txt"; char *ignore="\n !?()*-;:.,_\"[]"; int main(void){ int p=0, x, count, l, t=0,k=0; char name[LMAX][NMAX], word1[NMAX], word2[NMAX]; char *tp, *tp2; if((fp=fopen(fn,"r"))==NULL){ printf("Can't open '%s'.\n",fn); exit(1); } if((fp2=fopen(fn2,"w"))==NULL){ printf("Can't open '%s'.\n",fn2); exit(1); } for(count=0;count<LMAX;count++){ if(fgets(name[count],NMAX,fp)==NULL)break; p++; } for(count=0;count<p;count++){ for(x=0;x<NMAX;x++){ word1[x]=tolower(name[count][x]); } tp=word1; while((tp2=strtok(tp,ignore))!=NULL){ if(*tp2=='\''){ if(*(tp2+1)=='`') t=1; tp2++; } strcpy(word2,tp2); k=l=strlen(word2)-1; if(word2[k]==('\'' & 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); exit(1); } for(;;){ if(fgets(word3, NMAX,fp2)==NULL) break; n++; } fclose(fp2); count(fp2,n); } void count(FILE* fp2, int n){ int count, x, y=0; char *m=(char *)malloc(n*NMAX); char *xp,*yp; if(m==NULL){ return ; } if((fp2=fopen(fn2,"r"))==NULL){ printf("Can't open '%s'.\n", fn2); exit(1); } for(count=0,xp=m; count<n;count++,xp+=NMAX){ fgets(xp,NMAX,fp2); } qsort(m,n,NMAX,(int (*)(const void*, const void*))strcmp); count=1; for(x=0,xp=m,yp=m+NMAX;x<n-1;xp+=NMAX,yp+=NMAX,x++){ if(strcmp(xp,yp)==0){ y++; count++; } else{ count=1; } } printf("KIDN OF WORD:%d\n",n-y); if(m){ free(m); m=NULL; printf("%p\n",m); } fclose(fp2); } このプログラムを実行するとメモリリークになってしまいます どうしたら良いでしょうか?

  • ファイル

    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; }

  • 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でも良いような気がするのですが・・・

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

    以下のプログラムなのですが、引数を与えると下のようなエラーになります。 #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 で終了しました どうしたらよいのでしょうか?

  • C言語について

    以下のプログラムについてです test.txtというファイルから文字を読み込み、異なる単語の数を求めるプログラムです。 #include<stdio.h> #include<stdlib.h> #include<string.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"; int main(void){ int p=0, x, count, l,k, t=0; char name[LMAX][NMAX], word1[NMAX], word2[NMAX]; char *tp, *tp2; if((fp=fopen(fn,"r"))==NULL){ printf("Can't open '%s'.\n",fn); exit(1); } if((fp2=fopen(fn2,"w"))==NULL){ printf("Can't open '%s'.\n",fn2); exit(1); } for(count=0;count<LMAX;count++){ if(fgets(name[count],NMAX,fp)==NULL)break; p++; } for(count=0;count<p;count++){ for(x=0;x<NMAX;x++){ word1[x]=tolower(name[count][x]); } tp=word1; while((tp2=strtok(tp,"\n !?()*-;:.,_\"[]"))!=NULL){ if(*tp2=='\''){ if(*(tp2+1)=='`') t=1; tp2++; } strcpy(word2,tp2); k=l=strlen(word2)-1; if(word2[k]==('\'' & 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); exit(1); } for(;;){ if(fgets(word3, NMAX,fp2)==NULL) break; n++; } fclose(fp2); count(fp2,n); } void count(FILE* fp2, int n){ int count, x, y=0; char *m=(char *)malloc(n*NMAX); char *xp,*yp; if((fp2=fopen(fn2,"r"))==NULL){ printf("Can't open '%s'.\n", fn2); exit(1); } for(count=0,xp=m; count<n;count++,xp+=NMAX){ fgets(xp,NMAX,fp2); } qsort(m,n,NMAX,(int (*)(const void*, const void*))strcmp); count=1; for(x=0,xp=m,yp=m+NMAX;x<n-1;xp+=NMAX,yp+=NMAX,x++){ if(strcmp(xp,yp)==0){ y++; count++; } else{ sprintf(xp+strlen(xp)-1," (%d)",count); count=1; } }    printf("KIDN OF WORD:%d\n",n-y); free(m); fclose(fp2); } このプログラムを実行するとメモリリークになってしまいます。 どうしたら良いでしょうか?

  • C言語の質問です

    #include <stdio.h> #include <stdlib.h> int main(int argc, char *argv[]) { FILE *fpi, *fpo; unsigned char idat; /* 引数のチェック */ if (argc != 3) { fprintf(stderr, "Usage: %s [input] [output]\n", argv[0]); exit(1); } /* 入力画像のオープン */ if((fpi=fopen(argv[1], "rb")) == NULL){ fprintf(stderr, "input file open error\n"); exit(1); } /* 出力画像のオープン */ if((fpo=fopen(argv[2], "wb")) == NULL){ fprintf(stderr, "output file open error\n"); exit(1); } /* 入力画像の読込み */ while (fread(&idat, sizeof(unsigned char), 1, fpi) == 1){ /* 2倍の変換 */ if (idat * 2 > 255) { idat = 255; } else { idat = idat * 2; } /* 変換データの書出し */ if(fwrite(&idat, sizeof(unsigned char), 1, fpo) != 1){ fprintf(stderr, "data write error\n"); exit(1); } } fclose(fpi); fclose(fpo); return (0); } このプログラムをグレースケール化のプログラムに修正してください お願いします

専門家に質問してみよう