「word_replace.c」の編集履歴(バックアップ)一覧はこちら

word_replace.c」(2007/08/02 (木) 21:12:17) の最新版変更点

追加された行は緑色になります。

削除された行は赤色になります。

//c #include <stdio.h> #include <stdlib.h> #include <string.h> #define LINE_SIZE 256 #define CMD_SIZE 100 extern FILE *txtfile; //置換その1・・・単語検索その1の置換版 void word_replace1(char *txtname) { int i , j , k , l = 0 , h , n , m , g , LAST_EOF_LINE = 0; int line[1000] ; //単語出現数は1000回まで char str[LINE_SIZE], word[CMD_SIZE], word2[CMD_SIZE], c=1, shadow_name[L_tmpnam]; FILE *shadow ; tmpnam(shadow_name); printf("置換される前の文字列(編集前の今ある文字列)を入力して下さい\n"); fgets(word, CMD_SIZE, stdin); //単語のサイズは99まで for(i=1;c != EOF;i++) //1行読み込む毎にiをカウント { if((c = fgetc(txtfile)) == EOF ) //その行の一文字目がEOFなら { break ; //終了 } else if( c == '\n' ) //その行が単なる改行なら { j = 0 ; str[j] = '\n' ; //改行をstrにおさめて goto input1 ; //読み込み作業は飛ばす } str[0] = c ; //一文字目がEOFでも改行でもなかったら for(j=1;(c = fgetc(txtfile)) != '\n';j++) //改行するまでその行を読み込む { str[j] = c ; if( c == EOF ) //ファイルの最後が改行せずに終わっていたら { goto input1; //改行を入れることなく飛ばす } } str[j] = '\n' ; //改行をstrに入れる input1 : ; str[++j] = '\0' ; //最後にNULL文字を入れる for(j=0;str[j]!='\n';j++) //読み込んだ行の中に単語が含まれていないか探す { if( str[j] == EOF ) break; for(k=j;word[k-j]==str[k];k++) { if(word[k-j+1]=='\n') //含まれていたら { line[l] = i ; //その行番号をline[]に入れる l++; } } } for(k=0;k<j;k++) { str[k] = '\0' ; } } txtfile = freopen(txtname,"r",txtfile); //ここから、ファイル内容をshadowに置き換える printf("置き換えた後の文字列(編集後に残る文字列)を入力して下さい\n"); fgets(word2,CMD_SIZE,stdin); shadow = fopen(shadow_name,"w"); for(i=0;i<l;i++) //置換する前の単語のある行の手前まで { if( i == 0 ) { for(j=1;j<line[0];j++) { fgets(str,LINE_SIZE,txtfile); fputs(str,shadow); //内容をshadowにコピー } m = line[0] ; } else if( line[i] != line[i-1] ) //1行に複数ある場合は一度だけ { for(j=m+1;j<line[i];j++) { fgets(str,LINE_SIZE,txtfile); fputs(str,shadow); } m = line[i] ; } else { goto END1 ; } //置換する前の単語のある行にきたら fgets(str,LINE_SIZE,txtfile); //strにその行をコピー for(j=0,h=0;str[h+j]!='\n';j++) //行の中の単語が含まれてる位置を探す { if( str[h+j] == EOF ) break; for(k=h+j;word[k-(h+j)]==str[k];k++) { if(word[k-(h+j)+1]=='\n') //含まれていたら { for(g=h;g<h+j;g++) //その単語の手前までshadowにコピー { fputc(str[g],shadow); } for(n=0;word2[n]!='\n';n++) //置換した後の単語をshadowにコピー { fputc(word2[n],shadow); } h = k + 1; j = -1 ; break ; } } } //もうその行に置換する前の単語が無ければ for(k=h;str[k]!='\n' && str[k]!=EOF;k++)//残りをshadowにコピー { fputc(str[k],shadow); } if(str[k] == EOF ) //もし行の最後が改行でなくEOFで終わっていたら { LAST_EOF_LINE = 1 ; //最後の行は改行でなくEOFで終わっていることをマークし goto END2 ; //飛ぶ } fputc('\n',shadow); //そうでなければ行の最後は改行を入れる END1 : ; } //もうファイル中のそれ以降の行に置換する前の単語が無ければ c = 1 ; //最初のc == EOF を避けるため for(;c != EOF;) { if((c = fgetc(txtfile)) == EOF ) //その行の一文字目がEOFなら { break ; //終了 } else if( c == '\n' ) //その行が単なる改行なら { j = 0 ; str[j] = '\n' ; //改行をstrにおさめて goto input2 ; //読み込み作業は飛ばす } str[0] = c ; //一文字目がEOFでも改行でもなかったら for(j=1;(c = fgetc(txtfile)) != '\n';j++) //改行するまでその行を読み込む { str[j] = c ; if( c == EOF ) //ファイルの最後が改行せずに終わっていたら { goto input2; //改行を入れることなく飛ばす } } str[j] = '\n' ; //改行をstrに入れる input2 : ; str[++j] = '\0' ; //最後にNULL文字を入れる fputs(str,shadow); } END2 : ; txtfile = freopen(txtname,"w",txtfile); //両方のファイルをオープンし直して shadow = freopen(shadow_name,"r",shadow); /* 今回の行編集プログラミングにおいて最も問題となったのがファイルの終わり方で 改行せずにファイルが終了する場合に多くの注意が必要となった。 すなわち new\n \n old\n というファイルは改行の後にファイルが終了しているが new\n \n old では行末にEOFが来ることになる。こうした場合単にfgetsで行を読み取ると、最後にEOFの部分が記号で表示されてしまう という問題が生じた。そのため多くの場合一文字ずつ読み込んで書き込みを行う手法を取ってきたが、この置換関数では行末に EOFがあるファイルで、更にその最後の行を置換する場合、一文字ずつ読み込んで書き込みを行おうとすると何故かshadowファイル に謎の記号が後に続いてしまい書き込む元のファイルデータにそれを写してしまうことになった。ところがこのケースでfgetsに よる読み込みを行うと今度はEOFを記号として書き込むことなくうまく写し取ることに成功できるようになった。そこで今回は 最後の写しを行う段階で場合分けを行っている (説明が無いとあまりにも無駄な行動をしてるとしか思えないのでわざわざ記しておくことにしました) */ if( LAST_EOF_LINE == 0 ) { for(;(c = fgetc(shadow)) != EOF;) //shadowの中身をtxtfileにコピー { for(;c != '\n' && c != EOF ;c = fgetc(shadow)) { fputc(c,txtfile); } fputc('\n',txtfile); } } else { for(;fgets(str,LINE_SIZE - 1,shadow) != NULL;) //shadowの中身をコピー { fputs(str,txtfile); } } fclose(shadow); remove(shadow_name); return; } //置換その2・・・単語検索その2の置換版 void word_replace2(char *txtname) { int i , j , k , l = 0 , h , n , m , g ; int line[1000] ; //単語出現数は1000回まで char str[LINE_SIZE], word[CMD_SIZE], word2[CMD_SIZE], c = 1, shadow_name[L_tmpnam]; FILE *shadow ; tmpnam(shadow_name); printf("置換される前の単語(編集前の今ある単語)を入力して下さい\n"); fgets(word, CMD_SIZE, stdin); //単語のサイズは99まで for(i=1;c != EOF;i++) //1行読み込む毎にiをカウント { if((c = fgetc(txtfile)) == EOF ) //その行の一文字目がEOFなら { break ; //終了 } else if( c == '\n' ) //その行が単なる改行なら { j = 0 ; str[j] = '\n' ; //改行をstrにおさめて goto input0 ; //読み込み作業は飛ばす } str[0] = c ; //一文字目がEOFでも改行でもなかったら for(j=1;(c = fgetc(txtfile)) != '\n';j++) //改行するまでその行を読み込む { str[j] = c ; if( c == EOF ) //ファイルの最後が改行せずに終わっていたら { goto input0; //改行を入れることなく飛ばす } } str[j] = '\n' ; //改行をstrに入れる input0 : ; str[++j] = '\0' ; //最後にNULL文字を入れる for(j=0;str[j]!='\n';j++) //読み込んだ行の中に単語が含まれていないか探す { if( str[j] == EOF ) break; for(k=j;word[k-j]==str[k];k++) { if(word[k-j+1]=='\n') //含まれていたら { if( j == 0 || str[j-1] == ' ' ) //この2行でそれが単語そのものか判定 if( str[k+1] == ' ' || str[k+1] == '\n' || str[k+1] == EOF ) { line[l] = i ; //その行番号をline[]に入れる l++; } } } } for(k=0;k<j;k++) { str[k] = '\0' ; } } txtfile = freopen(txtname,"r",txtfile); //ここから、ファイル内容をshadowに置き換える printf("置き換えた後の単語(編集後に残る単語)を入力して下さい\n"); fgets(word2,CMD_SIZE,stdin); shadow = fopen(shadow_name,"w"); for(i=0;i<l;i++) //置換する前の単語のある行の手前まで { if( i == 0 ) { for(j=1;j<line[0];j++) { fgets(str,LINE_SIZE,txtfile); fputs(str,shadow); //内容をshadowにコピー } m = line[0] ; } else if( line[i] != line[i-1] ) //1行に複数ある場合は一度だけ { for(j=m+1;j<line[i];j++) { fgets(str,LINE_SIZE,txtfile); fputs(str,shadow); } m = line[i] ; } else { goto END1 ; } //置換する前の単語のある行にきたらまずその行をstrにコピー if((c = fgetc(txtfile)) == EOF ) //その行の一文字目がEOFなら { break ; //終了 } else if( c == '\n' ) //その行が単なる改行なら { j = 0 ; str[j] = '\n' ; //改行をstrにおさめて goto input1 ; //読み込み作業は飛ばす } str[0] = c ; //一文字目がEOFでも改行でもなかったら for(l=1;(c = fgetc(txtfile)) != '\n';l++) //改行するまでその行を読み込む { str[l] = c ; if( c == EOF ) //ファイルの最後が改行せずに終わっていたら { goto input1; //改行を入れることなく飛ばす } } str[l] = '\n' ; //改行をstrに入れる input1 : ; str[++l] = '\0' ; //最後にNULL文字を入れる //これでstrにコピーをし終えた for(j=0,h=0;str[h+j]!='\n';j++) //行の中の単語が含まれてる位置を探す { if( str[h+j] == EOF ) break; for(k=h+j;word[k-(h+j)]==str[k];k++) { if(word[k-(h+j)+1]=='\n') //含まれていたら { if( h+j == 0 || str[h+j-1] == ' ' ) //この2行でそれが単語そのものか判定 if( str[k+1] == ' ' || str[k+1] == '\n' || str[k+1] == EOF ) { for(g=h;g<h+j;g++) //その単語の手前までshadowにコピー { fputc(str[g],shadow); } for(n=0;word2[n]!='\n';n++) //置換した後の単語をshadowにコピー { fputc(word2[n],shadow); } h = k + 1; j = -1 ; break ; } } } } //もうその行に置換する前の単語が無ければ for(k=h;str[k]!='\n' && str[k]!=EOF;k++)//残りをshadowにコピー { fputc(str[k],shadow); } if(str[k] == EOF ) //もし行の最後が改行でなくEOFで終わっていたら { goto END2 ; //飛ぶ } fputc('\n',shadow); //そうでなければ行の最後は改行を入れる END1 : ; for(;k>=0;k--) str[k] = '\0'; } //もうファイル中のそれ以降の行に置換する前の単語が無ければ c = 1 ; //最初のc == EOF を避けるため for(;c != EOF;) { if((c = fgetc(txtfile)) == EOF ) //その行の一文字目がEOFなら { break ; //終了 } else if( c == '\n' ) //その行が単なる改行なら { j = 0 ; str[j] = '\n' ; //改行をstrにおさめて goto input2 ; //読み込み作業は飛ばす } str[0] = c ; //一文字目がEOFでも改行でもなかったら for(j=1;(c = fgetc(txtfile)) != '\n';j++) //改行するまでその行を読み込む { str[j] = c ; if( c == EOF ) //ファイルの最後が改行せずに終わっていたら { goto input2; //改行を入れることなく飛ばす } } str[j] = '\n' ; //改行をstrに入れる input2 : ; str[++j] = '\0' ; //最後にNULL文字を入れる fputs(str,shadow); } END2 : ; txtfile = freopen(txtname,"w",txtfile); //両方のファイルをオープンし直して shadow = freopen(shadow_name,"r",shadow); for(;(c = fgetc(shadow)) != EOF;) //shadowの中身をtxtfileにコピー { for(;c != '\n' && c != EOF ;c = fgetc(shadow)) { fputc(c,txtfile); } if( c == EOF ) ; else fputc('\n',txtfile); } fclose(shadow); remove(shadow_name); return; }
//c #include <stdio.h> #include <stdlib.h> #include <string.h> #define LINE_SIZE 256 #define CMD_SIZE 100 extern FILE *txtfile; //置換その1・・・単語検索その1の置換版 void word_replace1(char *txtname) { int i , j , k , l = 0 , h , n , m , g ; int line[1000] ; //単語出現数は1000回まで char str[LINE_SIZE], word[CMD_SIZE], word2[CMD_SIZE], c = 1, shadow_name[L_tmpnam]; FILE *shadow ; tmpnam(shadow_name); printf("置換される前の単語(編集前の今ある単語)を入力して下さい\n"); fgets(word, CMD_SIZE, stdin); //単語のサイズは99まで for(i=1;c != EOF;i++) //1行読み込む毎にiをカウント { if((c = fgetc(txtfile)) == EOF ) //その行の一文字目がEOFなら { break ; //終了 } else if( c == '\n' ) //その行が単なる改行なら { j = 0 ; str[j] = '\n' ; //改行をstrにおさめて goto input0 ; //読み込み作業は飛ばす } str[0] = c ; //一文字目がEOFでも改行でもなかったら for(j=1;(c = fgetc(txtfile)) != '\n';j++) //改行するまでその行を読み込む { str[j] = c ; if( c == EOF ) //ファイルの最後が改行せずに終わっていたら { goto input0; //改行を入れることなく飛ばす } } str[j] = '\n' ; //改行をstrに入れる input0 : ; str[++j] = '\0' ; //最後にNULL文字を入れる for(j=0;str[j]!='\n';j++) //読み込んだ行の中に単語が含まれていないか探す { if( str[j] == EOF ) break; for(k=j;word[k-j]==str[k];k++) { if(word[k-j+1]=='\n') //含まれていたら { line[l] = i ; //その行番号をline[]に入れる l++; } } } for(k=0;k<j;k++) { str[k] = '\0' ; } } txtfile = freopen(txtname,"r",txtfile); //ここから、ファイル内容をshadowに置き換える printf("置き換えた後の単語(編集後に残る単語)を入力して下さい\n"); fgets(word2,CMD_SIZE,stdin); shadow = fopen(shadow_name,"w"); for(i=0;i<l;i++) //置換する前の単語のある行の手前まで { if( i == 0 ) { for(j=1;j<line[0];j++) { fgets(str,LINE_SIZE,txtfile); fputs(str,shadow); //内容をshadowにコピー } m = line[0] ; } else if( line[i] != line[i-1] ) //1行に複数ある場合は一度だけ { for(j=m+1;j<line[i];j++) { fgets(str,LINE_SIZE,txtfile); fputs(str,shadow); } m = line[i] ; } else { goto END1 ; } //置換する前の単語のある行にきたらまずその行をstrにコピー if((c = fgetc(txtfile)) == EOF ) //その行の一文字目がEOFなら { break ; //終了 } else if( c == '\n' ) //その行が単なる改行なら { j = 0 ; str[j] = '\n' ; //改行をstrにおさめて goto input1 ; //読み込み作業は飛ばす } str[0] = c ; //一文字目がEOFでも改行でもなかったら for(l=1;(c = fgetc(txtfile)) != '\n';l++) //改行するまでその行を読み込む { str[l] = c ; if( c == EOF ) //ファイルの最後が改行せずに終わっていたら { goto input1; //改行を入れることなく飛ばす } } str[l] = '\n' ; //改行をstrに入れる input1 : ; str[++l] = '\0' ; //最後にNULL文字を入れる //これでstrにコピーをし終えた for(j=0,h=0;str[h+j]!='\n';j++) //行の中の単語が含まれてる位置を探す { if( str[h+j] == EOF ) break; for(k=h+j;word[k-(h+j)]==str[k];k++) { if(word[k-(h+j)+1]=='\n') //含まれていたら { for(g=h;g<h+j;g++) //その単語の手前までshadowにコピー { fputc(str[g],shadow); } for(n=0;word2[n]!='\n';n++) //置換した後の単語をshadowにコピー { fputc(word2[n],shadow); } h = k + 1; j = -1 ; break ; } } } //もうその行に置換する前の単語が無ければ for(k=h;str[k]!='\n' && str[k]!=EOF;k++)//残りをshadowにコピー { fputc(str[k],shadow); } if(str[k] == EOF ) //もし行の最後が改行でなくEOFで終わっていたら { goto END2 ; //飛ぶ } fputc('\n',shadow); //そうでなければ行の最後は改行を入れる END1 : ; for(;k>=0;k--) str[k] = '\0'; } //もうファイル中のそれ以降の行に置換する前の単語が無ければ c = 1 ; //最初のc == EOF を避けるため for(;c != EOF;) { if((c = fgetc(txtfile)) == EOF ) //その行の一文字目がEOFなら { break ; //終了 } else if( c == '\n' ) //その行が単なる改行なら { j = 0 ; str[j] = '\n' ; //改行をstrにおさめて goto input2 ; //読み込み作業は飛ばす } str[0] = c ; //一文字目がEOFでも改行でもなかったら for(j=1;(c = fgetc(txtfile)) != '\n';j++) //改行するまでその行を読み込む { str[j] = c ; if( c == EOF ) //ファイルの最後が改行せずに終わっていたら { goto input2; //改行を入れることなく飛ばす } } str[j] = '\n' ; //改行をstrに入れる input2 : ; str[++j] = '\0' ; //最後にNULL文字を入れる fputs(str,shadow); } END2 : ; txtfile = freopen(txtname,"w",txtfile); //両方のファイルをオープンし直して shadow = freopen(shadow_name,"r",shadow); for(;(c = fgetc(shadow)) != EOF;) //shadowの中身をtxtfileにコピー { for(;c != '\n' && c != EOF ;c = fgetc(shadow)) { fputc(c,txtfile); } if( c == EOF ) ; else fputc('\n',txtfile); } fclose(shadow); remove(shadow_name); return; } //置換その2・・・単語検索その2の置換版 void word_replace2(char *txtname) { int i , j , k , l = 0 , h , n , m , g ; int line[1000] ; //単語出現数は1000回まで char str[LINE_SIZE], word[CMD_SIZE], word2[CMD_SIZE], c = 1, shadow_name[L_tmpnam]; FILE *shadow ; tmpnam(shadow_name); printf("置換される前の単語(編集前の今ある単語)を入力して下さい\n"); fgets(word, CMD_SIZE, stdin); //単語のサイズは99まで for(i=1;c != EOF;i++) //1行読み込む毎にiをカウント { if((c = fgetc(txtfile)) == EOF ) //その行の一文字目がEOFなら { break ; //終了 } else if( c == '\n' ) //その行が単なる改行なら { j = 0 ; str[j] = '\n' ; //改行をstrにおさめて goto input0 ; //読み込み作業は飛ばす } str[0] = c ; //一文字目がEOFでも改行でもなかったら for(j=1;(c = fgetc(txtfile)) != '\n';j++) //改行するまでその行を読み込む { str[j] = c ; if( c == EOF ) //ファイルの最後が改行せずに終わっていたら { goto input0; //改行を入れることなく飛ばす } } str[j] = '\n' ; //改行をstrに入れる input0 : ; str[++j] = '\0' ; //最後にNULL文字を入れる for(j=0;str[j]!='\n';j++) //読み込んだ行の中に単語が含まれていないか探す { if( str[j] == EOF ) break; for(k=j;word[k-j]==str[k];k++) { if(word[k-j+1]=='\n') //含まれていたら { if( j == 0 || str[j-1] == ' ' ) //この2行でそれが単語そのものか判定 if( str[k+1] == ' ' || str[k+1] == '\n' || str[k+1] == EOF ) { line[l] = i ; //その行番号をline[]に入れる l++; } } } } for(k=0;k<j;k++) { str[k] = '\0' ; } } txtfile = freopen(txtname,"r",txtfile); //ここから、ファイル内容をshadowに置き換える printf("置き換えた後の単語(編集後に残る単語)を入力して下さい\n"); fgets(word2,CMD_SIZE,stdin); shadow = fopen(shadow_name,"w"); for(i=0;i<l;i++) //置換する前の単語のある行の手前まで { if( i == 0 ) { for(j=1;j<line[0];j++) { fgets(str,LINE_SIZE,txtfile); fputs(str,shadow); //内容をshadowにコピー } m = line[0] ; } else if( line[i] != line[i-1] ) //1行に複数ある場合は一度だけ { for(j=m+1;j<line[i];j++) { fgets(str,LINE_SIZE,txtfile); fputs(str,shadow); } m = line[i] ; } else { goto END1 ; } //置換する前の単語のある行にきたらまずその行をstrにコピー if((c = fgetc(txtfile)) == EOF ) //その行の一文字目がEOFなら { break ; //終了 } else if( c == '\n' ) //その行が単なる改行なら { j = 0 ; str[j] = '\n' ; //改行をstrにおさめて goto input1 ; //読み込み作業は飛ばす } str[0] = c ; //一文字目がEOFでも改行でもなかったら for(l=1;(c = fgetc(txtfile)) != '\n';l++) //改行するまでその行を読み込む { str[l] = c ; if( c == EOF ) //ファイルの最後が改行せずに終わっていたら { goto input1; //改行を入れることなく飛ばす } } str[l] = '\n' ; //改行をstrに入れる input1 : ; str[++l] = '\0' ; //最後にNULL文字を入れる //これでstrにコピーをし終えた for(j=0,h=0;str[h+j]!='\n';j++) //行の中の単語が含まれてる位置を探す { if( str[h+j] == EOF ) break; for(k=h+j;word[k-(h+j)]==str[k];k++) { if(word[k-(h+j)+1]=='\n') //含まれていたら { if( h+j == 0 || str[h+j-1] == ' ' ) //この2行でそれが単語そのものか判定 if( str[k+1] == ' ' || str[k+1] == '\n' || str[k+1] == EOF ) { for(g=h;g<h+j;g++) //その単語の手前までshadowにコピー { fputc(str[g],shadow); } for(n=0;word2[n]!='\n';n++) //置換した後の単語をshadowにコピー { fputc(word2[n],shadow); } h = k + 1; j = -1 ; break ; } } } } //もうその行に置換する前の単語が無ければ for(k=h;str[k]!='\n' && str[k]!=EOF;k++)//残りをshadowにコピー { fputc(str[k],shadow); } if(str[k] == EOF ) //もし行の最後が改行でなくEOFで終わっていたら { goto END2 ; //飛ぶ } fputc('\n',shadow); //そうでなければ行の最後は改行を入れる END1 : ; for(;k>=0;k--) str[k] = '\0'; } //もうファイル中のそれ以降の行に置換する前の単語が無ければ c = 1 ; //最初のc == EOF を避けるため for(;c != EOF;) { if((c = fgetc(txtfile)) == EOF ) //その行の一文字目がEOFなら { break ; //終了 } else if( c == '\n' ) //その行が単なる改行なら { j = 0 ; str[j] = '\n' ; //改行をstrにおさめて goto input2 ; //読み込み作業は飛ばす } str[0] = c ; //一文字目がEOFでも改行でもなかったら for(j=1;(c = fgetc(txtfile)) != '\n';j++) //改行するまでその行を読み込む { str[j] = c ; if( c == EOF ) //ファイルの最後が改行せずに終わっていたら { goto input2; //改行を入れることなく飛ばす } } str[j] = '\n' ; //改行をstrに入れる input2 : ; str[++j] = '\0' ; //最後にNULL文字を入れる fputs(str,shadow); } END2 : ; txtfile = freopen(txtname,"w",txtfile); //両方のファイルをオープンし直して shadow = freopen(shadow_name,"r",shadow); for(;(c = fgetc(shadow)) != EOF;) //shadowの中身をtxtfileにコピー { for(;c != '\n' && c != EOF ;c = fgetc(shadow)) { fputc(c,txtfile); } if( c == EOF ) ; else fputc('\n',txtfile); } fclose(shadow); remove(shadow_name); return; }

表示オプション

横に並べて表示:
変化行の前後のみ表示: