「検索、置換、挿入修正プログラムソース 飯尾」の編集履歴(バックアップ)一覧はこちら

検索、置換、挿入修正プログラムソース 飯尾」(2007/08/02 (木) 00:34:10) の最新版変更点

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

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

//c //変更点だけ載せておきますー・・・最後に削除の注意文追加版も載せておきます。いやprintf文追加しただけですが(汗) void word_search1(FILE *txt, char *txtname); void word_search2(FILE *txt, char *txtname); void word_replace1(FILE *txt, char *txtname); void word_replace2(FILE *txt, char *txtname); //機能はここに追加 void execmd(FILE *txt, FILE *temp, FILE *undo, char *txtname, char *undo_text, char *temp_cmd, int *p){ if(strcmp(temp_cmd, "l\n") == 0 || strcmp(temp_cmd, "L\n") == 0) display_all(txt); //すべて表示 if(atoi(temp_cmd) != 0) make_undofile(txt, temp, undo, txtname, undo_text, temp_cmd, p); //一行編集に入る前にundo用ファイルに記録 if(strcmp(temp_cmd, "e\n") == 0 || strcmp(temp_cmd, "E\n") == 0) save_end(p); //保存して終了 if(strcmp(temp_cmd, "n\n") == 0 || strcmp(temp_cmd, "N\n") == 0) not_save(txt,temp,txtname,p); //保存しないで終了 if(strcmp(temp_cmd, "u\n") == 0 || strcmp(temp_cmd, "U\n") == 0) un_do(txt,undo,txtname,undo_text); //前回の編集前の状態に戻す(undo) if(strcmp(temp_cmd, "s1\n") == 0 || strcmp(temp_cmd, "S1\n") == 0) word_search1(txt,txtname); //単語検索その1 if(strcmp(temp_cmd, "s2\n") == 0 || strcmp(temp_cmd, "S2\n") == 0) word_search2(txt,txtname); //単語検索その2 if(strcmp(temp_cmd, "r1\n") == 0 || strcmp(temp_cmd, "R1\n") == 0) make_undofile(txt, temp, undo, txtname, undo_text, temp_cmd, p);//置換に入る前にundo用ファイルに記録 if(strcmp(temp_cmd, "r2\n") == 0 || strcmp(temp_cmd, "R2\n") == 0) make_undofile(txt, temp, undo, txtname, undo_text, temp_cmd, p);//置換に入る前にundo用ファイルに記録 if(strcmp(temp_cmd, "d\n") == 0 || strcmp(temp_cmd, "D\n") == 0) make_undofile(txt, temp, undo, txtname, undo_text, temp_cmd, p);//行削除に入る前にundo用ファイルに記録 if(strcmp(temp_cmd, "i\n") == 0 || strcmp(temp_cmd, "I\n") == 0) make_undofile(txt, temp, undo, txtname, undo_text, temp_cmd, p);//行挿入に入る前にundo用ファイルに記録 return; } //undo用ファイルの保存 void make_undofile(FILE *txt, FILE *temp, FILE *undo, char *txtname, char *undo_text, char *temp_cmd, int *p){ char c; //txt→undoファイル用 undo = fopen(undo_text,"w"); while( (c = fgetc(txt)) != EOF ) //編集直前の状態を保存する { fputc(c,undo); } txt = freopen(txtname,"r",txt); //もう一度txtをオープンしておく fclose(undo); //undoは閉じておく。 if(atoi(temp_cmd) != 0) one_row_edit(txt, temp, undo, atoi(temp_cmd), txtname, undo_text, p); //一行編集 if(strcmp(temp_cmd, "r1\n") == 0 || strcmp(temp_cmd, "R1\n") == 0) word_replace1(txt,txtname); //置換その1 if(strcmp(temp_cmd, "r2\n") == 0 || strcmp(temp_cmd, "R2\n") == 0) word_replace2(txt,txtname); //置換その2 if(strcmp(temp_cmd, "d\n") == 0 || strcmp(temp_cmd, "D\n") == 0) line_delete(txt,txtname); //行削除 if(strcmp(temp_cmd, "i\n") == 0 || strcmp(temp_cmd, "I\n") == 0) line_insert(txt,txtname); //行挿入 } //単語検索その1・・・単語を含んだ文字列の検索。例えばprogramを検索するならprogramingも表示する void word_search1(FILE *txt, char *txtname) { int i , j , k , l = 0 ; int line[1000] ; //単語出現数は1000回まで char str[LINE_SIZE], word[CMD_SIZE]; printf("検索したい単語を入力して下さい\n"); fgets(word, CMD_SIZE, stdin); //単語のサイズは99まで for(i=1;!feof(txt);i++) //1行読み込む毎にiをカウント { fgets(str,LINE_SIZE,txt); //まず一行全部読み込む 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' ; } } txt = freopen(txtname,"r",txt); //line[]に入れた行番号からその行を出力する for(i=0;i<l;i++) { if( i == 0 ) { for(j=1;j<=line[0];j++) fgets(str,LINE_SIZE,txt); k = line[0]; printf("%d : %s",line[0],str); if( feof(txt) ) { printf("\n"); } } else if( line[i] != line[i-1] ) //1行にいくつもある場合はとばす { for(j=k+1;j<=line[i];j++) fgets(str,LINE_SIZE,txt); k = line[i]; printf("%d : %s",line[i],str); if( feof(txt) ) { printf("\n"); } } } } //単語検索その2・・・単語そのものの検索。例えばprogramを検索するのにprogramingを検索してしまわないようにしている。 void word_search2(FILE *txt, char *txtname) { int i , j , k , l = 0 ; int line[1000] ; //単語出現数は1000回まで char str[LINE_SIZE], word[CMD_SIZE]; printf("検索したい単語を入力して下さい\n"); fgets(word, CMD_SIZE, stdin); //単語のサイズは99まで for(i=1;!feof(txt);i++) //1行読み込む毎にiをカウント { fgets(str,LINE_SIZE,txt); //まず一行全部読み込む 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' ; } } txt = freopen(txtname,"r",txt); //line[]に入れた行番号からその行を出力する for(i=0;i<l;i++) { if( i == 0 ) { for(j=1;j<=line[0];j++) fgets(str,LINE_SIZE,txt); k = line[0]; printf("%d : %s",line[0],str); if( feof(txt) ) { printf("\n"); } } else if( line[i] != line[i-1] ) //1行にいくつもある場合はとばす { for(j=k+1;j<=line[i];j++) fgets(str,LINE_SIZE,txt); k = line[i]; printf("%d : %s",line[i],str); if( feof(txt) ) { printf("\n"); } } } } //置換その1・・・単語検索その1の置換版 void word_replace1(FILE *txt, 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(txt)) == EOF ) //その行の一文字目がEOFなら { break ; //終了 } else if( c == '\n' ) //その行が単なる改行なら { j = 0 ; str[j] = '\n' ; //改行をstrにおさめて goto input1 ; //読み込み作業は飛ばす } str[0] = c ; //一文字目がEOFでも改行でもなかったら for(j=1;(c = fgetc(txt)) != '\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' ; } } txt = freopen(txtname,"r",txt); //ここから、ファイル内容を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,txt); 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,txt); fputs(str,shadow); } m = line[i] ; } else { goto END1 ; } //置換する前の単語のある行にきたら fgets(str,LINE_SIZE,txt); //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(txt)) == EOF ) //その行の一文字目がEOFなら { break ; //終了 } else if( c == '\n' ) //その行が単なる改行なら { j = 0 ; str[j] = '\n' ; //改行をstrにおさめて goto input2 ; //読み込み作業は飛ばす } str[0] = c ; //一文字目がEOFでも改行でもなかったら for(j=1;(c = fgetc(txt)) != '\n';j++) //改行するまでその行を読み込む { str[j] = c ; if( c == EOF ) //ファイルの最後が改行せずに終わっていたら { goto input2; //改行を入れることなく飛ばす } } str[j] = '\n' ; //改行をstrに入れる input2 : ; str[++j] = '\0' ; //最後にNULL文字を入れる fputs(str,shadow); } END2 : ; txt = freopen(txtname,"w",txt); //両方のファイルをオープンし直して 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の中身をtxtにコピー { for(;c != '\n' && c != EOF ;c = fgetc(shadow)) { fputc(c,txt); } fputc('\n',txt); } } else { for(;fgets(str,LINE_SIZE - 1,shadow) != NULL;) //shadowの中身をコピー { fputs(str,txt); } } fclose(shadow); remove(shadow_name); return; } //置換その2・・・単語検索その2の置換版 void word_replace2(FILE *txt, 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(txt)) == EOF ) //その行の一文字目がEOFなら { break ; //終了 } else if( c == '\n' ) //その行が単なる改行なら { j = 0 ; str[j] = '\n' ; //改行をstrにおさめて goto input1 ; //読み込み作業は飛ばす } str[0] = c ; //一文字目がEOFでも改行でもなかったら for(j=1;(c = fgetc(txt)) != '\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') //含まれていたら { 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' ; } } txt = freopen(txtname,"r",txt); //ここから、ファイル内容を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,txt); 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,txt); fputs(str,shadow); } m = line[i] ; } else { goto END1 ; } //置換する前の単語のある行にきたら fgets(str,LINE_SIZE,txt); //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で終わっていたら { LAST_EOF_LINE = 1 ; //最後の行は改行でなくEOFで終わっていることをマークし goto END2 ; //飛ぶ } fputc('\n',shadow); //そうでなければ行の最後は改行を入れる END1 : ; } //もうファイル中のそれ以降の行に置換する前の単語が無ければ c = 1 ; //最初のc == EOF を避けるため for(;c != EOF;) { if((c = fgetc(txt)) == EOF ) //その行の一文字目がEOFなら { break ; //終了 } else if( c == '\n' ) //その行が単なる改行なら { j = 0 ; str[j] = '\n' ; //改行をstrにおさめて goto input2 ; //読み込み作業は飛ばす } str[0] = c ; //一文字目がEOFでも改行でもなかったら for(j=1;(c = fgetc(txt)) != '\n';j++) //改行するまでその行を読み込む { str[j] = c ; if( c == EOF ) //ファイルの最後が改行せずに終わっていたら { goto input2; //改行を入れることなく飛ばす } } str[j] = '\n' ; //改行をstrに入れる input2 : ; str[++j] = '\0' ; //最後にNULL文字を入れる fputs(str,shadow); } END2 : ; txt = freopen(txtname,"w",txt); //両方のファイルをオープンし直して 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の中身をtxtにコピー { for(;c != '\n' && c != EOF ;c = fgetc(shadow)) { fputc(c,txt); } fputc('\n',txt); } } else { for(;fgets(str,LINE_SIZE - 1,shadow) != NULL;) //shadowの中身をコピー { fputs(str,txt); } } fclose(shadow); remove(shadow_name); return; } //行挿入 void line_insert(FILE *txt, char *txtname) { //ほぼ行削除と同じ構造 int i , j ; FILE *shadow; char c = 1, line[10], str[LINE_SIZE], shadow_name[L_tmpnam] ; tmpnam(shadow_name); printf("挿入したい行番号を入力して下さい\n"); fgets(line,9,stdin); //挿入したい行を入力してもらう。 if( atoi(line) <= 0 ) { printf("行番号が不正です。\n"); return; } shadow = fopen(shadow_name,"w"); if( atoi(line) == 1 ) //もし1行目に挿入したい場合は先に入力をする { fgets(str,LINE_SIZE,stdin); //挿入する内容を入力 fputs(str,shadow); //それをコピー } //あとは2行目以降に挿入したい場合と同じ動きをする for(i=1;c != EOF;i++) { if((c = fgetc(txt)) == EOF ) //その行の一文字目がEOFなら { break ; //終了 } else if( c == '\n' ) //その行が単なる改行なら { j = 0 ; str[j] = '\n' ; //改行をstrにおさめて goto input ; //読み込み作業は飛ばす } str[0] = c ; //一文字目がEOFでも改行でもなかったら for(j=1;(c = fgetc(txt)) != '\n';j++) //改行するまでその行を読み込む { str[j] = c ; if( c == EOF ) //ファイルの最後が改行せずに終わっていたら { goto input; //改行を入れることなく飛ばす } } str[j] = '\n' ; //改行をstrに入れる input : ; str[++j] = '\0' ; //最後にNULL文字を入れる if( i != atoi(line) - 1 ) //挿入する手前以外の行は普通にshadowにコピー { fputs(str,shadow); } else //挿入する手前の行は { fputs(str,shadow); //まず手前の行の内容をコピー printf("挿入したい文章を入力して下さい\n"); fgets(str,LINE_SIZE,stdin); //挿入する内容を入力 fputs(str,shadow); //それをコピー //通常の動きに戻る } } if( atoi(line) > i ) { printf("行番号が不正です。\n"); } txt = freopen(txtname,"w",txt); //両方のファイルをオープンし直して shadow = freopen(shadow_name,"r",shadow); for(;(c = fgetc(shadow)) != EOF;) //shadowの中身をtxtにコピー { for(;c != '\n' && c != EOF;c = fgetc(shadow)) { fputc(c,txt); } fputc('\n',txt); } fclose(shadow); remove(shadow_name); return; } //行削除 void line_delete(FILE *txt, char *txtname) { int i , j ; FILE *shadow; char c = 1, line[10], str[LINE_SIZE], shadow_name[L_tmpnam] ; tmpnam(shadow_name); printf("削除したい行番号を入力して下さい\n"); fgets(line,9,stdin); //削除したい行を入力してもらう if( atoi(line) < 1 ) { printf("行番号が不正です。\n"); return; } shadow = fopen(shadow_name,"w"); for(i=1;c != EOF;i++) { if((c = fgetc(txt)) == EOF ) //その行の一文字目がEOFなら { break ; //終了 } else if( c == '\n' ) //その行が単なる改行なら { j = 0 ; str[j] = '\n' ; //改行をstrにおさめて goto input ; //読み込み作業は飛ばす } str[0] = c ; //一文字目がEOFでも改行でもなかったら for(j=1;(c = fgetc(txt)) != '\n';j++) //改行するまでその行を読み込む { str[j] = c ; if( c == EOF ) //ファイルの最後が改行せずに終わっていたら { goto input; //改行を入れることなく飛ばす } } str[j] = '\n' ; //改行をstrに入れる input : ; str[++j] = '\0' ; //最後にNULL文字を入れる if( i != atoi(line) ) //削除しない行はshadowにコピー { fputs(str,shadow); } //削除する行はコピーせずに読み飛ばす } if( atoi(line) >= i ) { printf("行番号が不正です。\n"); } txt = freopen(txtname,"w",txt); //両方のファイルをオープンし直して shadow = freopen(shadow_name,"r",shadow); for(;(c = fgetc(shadow)) != EOF;) //shadowの中身をtxtにコピー { for(;c != '\n' && c != EOF ;c = fgetc(shadow)) { fputc(c,txt); } fputc('\n',txt); } fclose(shadow); remove(shadow_name); return; }
//c //変更点だけ載せておきますー・・・最後に削除の注意文追加版も載せておきます。いやprintf文追加しただけですが(汗) void word_search1(FILE *txt, char *txtname); void word_search2(FILE *txt, char *txtname); void word_replace1(FILE *txt, char *txtname); void word_replace2(FILE *txt, char *txtname); //機能はここに追加 void execmd(FILE *txt, FILE *temp, FILE *undo, char *txtname, char *undo_text, char *temp_cmd, int *p){ if(strcmp(temp_cmd, "l\n") == 0 || strcmp(temp_cmd, "L\n") == 0) display_all(txt); //すべて表示 if(atoi(temp_cmd) != 0) make_undofile(txt, temp, undo, txtname, undo_text, temp_cmd, p); //一行編集に入る前にundo用ファイルに記録 if(strcmp(temp_cmd, "e\n") == 0 || strcmp(temp_cmd, "E\n") == 0) save_end(p); //保存して終了 if(strcmp(temp_cmd, "n\n") == 0 || strcmp(temp_cmd, "N\n") == 0) not_save(txt,temp,txtname,p); //保存しないで終了 if(strcmp(temp_cmd, "u\n") == 0 || strcmp(temp_cmd, "U\n") == 0) un_do(txt,undo,txtname,undo_text); //前回の編集前の状態に戻す(undo) if(strcmp(temp_cmd, "s1\n") == 0 || strcmp(temp_cmd, "S1\n") == 0) word_search1(txt,txtname); //単語検索その1 if(strcmp(temp_cmd, "s2\n") == 0 || strcmp(temp_cmd, "S2\n") == 0) word_search2(txt,txtname); //単語検索その2 if(strcmp(temp_cmd, "r1\n") == 0 || strcmp(temp_cmd, "R1\n") == 0) make_undofile(txt, temp, undo, txtname, undo_text, temp_cmd, p);//置換に入る前にundo用ファイルに記録 if(strcmp(temp_cmd, "r2\n") == 0 || strcmp(temp_cmd, "R2\n") == 0) make_undofile(txt, temp, undo, txtname, undo_text, temp_cmd, p);//置換に入る前にundo用ファイルに記録 if(strcmp(temp_cmd, "d\n") == 0 || strcmp(temp_cmd, "D\n") == 0) make_undofile(txt, temp, undo, txtname, undo_text, temp_cmd, p);//行削除に入る前にundo用ファイルに記録 if(strcmp(temp_cmd, "i\n") == 0 || strcmp(temp_cmd, "I\n") == 0) make_undofile(txt, temp, undo, txtname, undo_text, temp_cmd, p);//行挿入に入る前にundo用ファイルに記録 return; } //undo用ファイルの保存 void make_undofile(FILE *txt, FILE *temp, FILE *undo, char *txtname, char *undo_text, char *temp_cmd, int *p){ char c; //txt→undoファイル用 undo = fopen(undo_text,"w"); while( (c = fgetc(txt)) != EOF ) //編集直前の状態を保存する { fputc(c,undo); } txt = freopen(txtname,"r",txt); //もう一度txtをオープンしておく fclose(undo); //undoは閉じておく。 if(atoi(temp_cmd) != 0) one_row_edit(txt, temp, undo, atoi(temp_cmd), txtname, undo_text, p); //一行編集 if(strcmp(temp_cmd, "r1\n") == 0 || strcmp(temp_cmd, "R1\n") == 0) word_replace1(txt,txtname); //置換その1 if(strcmp(temp_cmd, "r2\n") == 0 || strcmp(temp_cmd, "R2\n") == 0) word_replace2(txt,txtname); //置換その2 if(strcmp(temp_cmd, "d\n") == 0 || strcmp(temp_cmd, "D\n") == 0) line_delete(txt,txtname); //行削除 if(strcmp(temp_cmd, "i\n") == 0 || strcmp(temp_cmd, "I\n") == 0) line_insert(txt,txtname); //行挿入 } //単語検索その1・・・単語を含んだ文字列の検索。例えばprogramを検索するならprogramingも表示する void word_search1(FILE *txt, char *txtname) { int i , j , k , l = 0 ; int line[1000] ; //単語出現数は1000回まで char str[LINE_SIZE], word[CMD_SIZE]; printf("検索したい単語を入力して下さい\n"); fgets(word, CMD_SIZE, stdin); //単語のサイズは99まで for(i=1;!feof(txt);i++) //1行読み込む毎にiをカウント { fgets(str,LINE_SIZE,txt); //まず一行全部読み込む 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' ; } } txt = freopen(txtname,"r",txt); //line[]に入れた行番号からその行を出力する for(i=0;i<l;i++) { if( i == 0 ) { for(j=1;j<=line[0];j++) fgets(str,LINE_SIZE,txt); k = line[0]; printf("%d : %s",line[0],str); if( feof(txt) ) { printf("\n"); } } else if( line[i] != line[i-1] ) //1行にいくつもある場合はとばす { for(j=k+1;j<=line[i];j++) fgets(str,LINE_SIZE,txt); k = line[i]; printf("%d : %s",line[i],str); if( feof(txt) ) { printf("\n"); } } } } //単語検索その2・・・単語そのものの検索。例えばprogramを検索するのにprogramingを検索してしまわないようにしている。 void word_search2(FILE *txt, char *txtname) { int i , j , k , l = 0 ; int line[1000] ; //単語出現数は1000回まで char str[LINE_SIZE], word[CMD_SIZE]; printf("検索したい単語を入力して下さい\n"); fgets(word, CMD_SIZE, stdin); //単語のサイズは99まで for(i=1;!feof(txt);i++) //1行読み込む毎にiをカウント { fgets(str,LINE_SIZE,txt); //まず一行全部読み込む 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' ; } } txt = freopen(txtname,"r",txt); //line[]に入れた行番号からその行を出力する for(i=0;i<l;i++) { if( i == 0 ) { for(j=1;j<=line[0];j++) fgets(str,LINE_SIZE,txt); k = line[0]; printf("%d : %s",line[0],str); if( feof(txt) ) { printf("\n"); } } else if( line[i] != line[i-1] ) //1行にいくつもある場合はとばす { for(j=k+1;j<=line[i];j++) fgets(str,LINE_SIZE,txt); k = line[i]; printf("%d : %s",line[i],str); if( feof(txt) ) { printf("\n"); } } } } //単語検索その1・・・単語を含んだ文字列の検索。例えばprogramを検索するならprogramingも表示する void word_search1(FILE *txt, char *txtname) { int i , j , k , l = 0 ; int line[1000] ; //単語出現数は1000回まで char str[LINE_SIZE], word[CMD_SIZE]; printf("検索したい単語を入力して下さい\n"); fgets(word, CMD_SIZE, stdin); //単語のサイズは99まで for(i=1;!feof(txt);i++) //1行読み込む毎にiをカウント { fgets(str,LINE_SIZE,txt); //まず一行全部読み込む 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' ; } } txt = freopen(txtname,"r",txt); //line[]に入れた行番号からその行を出力する for(i=0;i<l;i++) { if( i == 0 ) { for(j=1;j<=line[0];j++) fgets(str,LINE_SIZE,txt); k = line[0]; printf("%d : %s",line[0],str); if( feof(txt) ) { printf("\n"); } } else if( line[i] != line[i-1] ) //1行にいくつもある場合はとばす { for(j=k+1;j<=line[i];j++) fgets(str,LINE_SIZE,txt); k = line[i]; printf("%d : %s",line[i],str); if( feof(txt) ) { printf("\n"); } } } } //単語検索その2・・・単語そのものの検索。例えばprogramを検索するのにprogramingを検索してしまわないようにしている。 void word_search2(FILE *txt, char *txtname) { int i , j , k , l = 0 ; int line[1000] ; //単語出現数は1000回まで char str[LINE_SIZE], word[CMD_SIZE]; printf("検索したい単語を入力して下さい\n"); fgets(word, CMD_SIZE, stdin); //単語のサイズは99まで for(i=1;!feof(txt);i++) //1行読み込む毎にiをカウント { fgets(str,LINE_SIZE,txt); //まず一行全部読み込む 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' ; } } txt = freopen(txtname,"r",txt); //line[]に入れた行番号からその行を出力する for(i=0;i<l;i++) { if( i == 0 ) { for(j=1;j<=line[0];j++) fgets(str,LINE_SIZE,txt); k = line[0]; printf("%d : %s",line[0],str); if( feof(txt) ) { printf("\n"); } } else if( line[i] != line[i-1] ) //1行にいくつもある場合はとばす { for(j=k+1;j<=line[i];j++) fgets(str,LINE_SIZE,txt); k = line[i]; printf("%d : %s",line[i],str); if( feof(txt) ) { printf("\n"); } } } } //置換その1・・・単語検索その1の置換版 void word_replace1(FILE *txt, 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(txt)) == EOF ) //その行の一文字目がEOFなら { break ; //終了 } else if( c == '\n' ) //その行が単なる改行なら { j = 0 ; str[j] = '\n' ; //改行をstrにおさめて goto input0 ; //読み込み作業は飛ばす } str[0] = c ; //一文字目がEOFでも改行でもなかったら for(j=1;(c = fgetc(txt)) != '\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' ; } } txt = freopen(txtname,"r",txt); //ここから、ファイル内容を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,txt); 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,txt); fputs(str,shadow); } m = line[i] ; } else { goto END1 ; } //置換する前の単語のある行にきたらまずその行をstrにコピー if((c = fgetc(txt)) == EOF ) //その行の一文字目がEOFなら { break ; //終了 } else if( c == '\n' ) //その行が単なる改行なら { j = 0 ; str[j] = '\n' ; //改行をstrにおさめて goto input1 ; //読み込み作業は飛ばす } str[0] = c ; //一文字目がEOFでも改行でもなかったら for(l=1;(c = fgetc(txt)) != '\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(txt)) == EOF ) //その行の一文字目がEOFなら { break ; //終了 } else if( c == '\n' ) //その行が単なる改行なら { j = 0 ; str[j] = '\n' ; //改行をstrにおさめて goto input2 ; //読み込み作業は飛ばす } str[0] = c ; //一文字目がEOFでも改行でもなかったら for(j=1;(c = fgetc(txt)) != '\n';j++) //改行するまでその行を読み込む { str[j] = c ; if( c == EOF ) //ファイルの最後が改行せずに終わっていたら { goto input2; //改行を入れることなく飛ばす } } str[j] = '\n' ; //改行をstrに入れる input2 : ; str[++j] = '\0' ; //最後にNULL文字を入れる fputs(str,shadow); } END2 : ; txt = freopen(txtname,"w",txt); //両方のファイルをオープンし直して shadow = freopen(shadow_name,"r",shadow); for(;(c = fgetc(shadow)) != EOF;) //shadowの中身をtxtにコピー { for(;c != '\n' && c != EOF ;c = fgetc(shadow)) { fputc(c,txt); } if( c == EOF ) ; else fputc('\n',txt); } fclose(shadow); remove(shadow_name); return; } //置換その2・・・単語検索その2の置換版 void word_replace2(FILE *txt, 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(txt)) == EOF ) //その行の一文字目がEOFなら { break ; //終了 } else if( c == '\n' ) //その行が単なる改行なら { j = 0 ; str[j] = '\n' ; //改行をstrにおさめて goto input0 ; //読み込み作業は飛ばす } str[0] = c ; //一文字目がEOFでも改行でもなかったら for(j=1;(c = fgetc(txt)) != '\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' ; } } txt = freopen(txtname,"r",txt); //ここから、ファイル内容を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,txt); 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,txt); fputs(str,shadow); } m = line[i] ; } else { goto END1 ; } //置換する前の単語のある行にきたらまずその行をstrにコピー if((c = fgetc(txt)) == EOF ) //その行の一文字目がEOFなら { break ; //終了 } else if( c == '\n' ) //その行が単なる改行なら { j = 0 ; str[j] = '\n' ; //改行をstrにおさめて goto input1 ; //読み込み作業は飛ばす } str[0] = c ; //一文字目がEOFでも改行でもなかったら for(l=1;(c = fgetc(txt)) != '\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(txt)) == EOF ) //その行の一文字目がEOFなら { break ; //終了 } else if( c == '\n' ) //その行が単なる改行なら { j = 0 ; str[j] = '\n' ; //改行をstrにおさめて goto input2 ; //読み込み作業は飛ばす } str[0] = c ; //一文字目がEOFでも改行でもなかったら for(j=1;(c = fgetc(txt)) != '\n';j++) //改行するまでその行を読み込む { str[j] = c ; if( c == EOF ) //ファイルの最後が改行せずに終わっていたら { goto input2; //改行を入れることなく飛ばす } } str[j] = '\n' ; //改行をstrに入れる input2 : ; str[++j] = '\0' ; //最後にNULL文字を入れる fputs(str,shadow); } END2 : ; txt = freopen(txtname,"w",txt); //両方のファイルをオープンし直して shadow = freopen(shadow_name,"r",shadow); for(;(c = fgetc(shadow)) != EOF;) //shadowの中身をtxtにコピー { for(;c != '\n' && c != EOF ;c = fgetc(shadow)) { fputc(c,txt); } if( c == EOF ) ; else fputc('\n',txt); } fclose(shadow); remove(shadow_name); return; } //行削除 void line_delete(FILE *txt, char *txtname) { int i , j ; FILE *shadow; char c = 1, line[10], str[LINE_SIZE], shadow_name[L_tmpnam] ; tmpnam(shadow_name); printf("削除したい行番号を入力して下さい\n"); fgets(line,9,stdin); //削除したい行を入力してもらう if( atoi(line) < 1 ) { printf("行番号が不正です。\n"); return; } shadow = fopen(shadow_name,"w"); for(i=1;c != EOF;i++) { if((c = fgetc(txt)) == EOF ) //その行の一文字目がEOFなら { break ; //終了 } else if( c == '\n' ) //その行が単なる改行なら { j = 0 ; str[j] = '\n' ; //改行をstrにおさめて goto input ; //読み込み作業は飛ばす } str[0] = c ; //一文字目がEOFでも改行でもなかったら for(j=1;(c = fgetc(txt)) != '\n';j++) //改行するまでその行を読み込む { str[j] = c ; if( c == EOF ) //ファイルの最後が改行せずに終わっていたら { goto input; //改行を入れることなく飛ばす } } str[j] = '\n' ; //改行をstrに入れる input : ; str[++j] = '\0' ; //最後にNULL文字を入れる if( i != atoi(line) ) //削除しない行はshadowにコピー { fputs(str,shadow); } //削除する行はコピーせずに読み飛ばす } if( atoi(line) >= i ) { printf("行番号が不正です。\n"); } txt = freopen(txtname,"w",txt); //両方のファイルをオープンし直して shadow = freopen(shadow_name,"r",shadow); for(;(c = fgetc(shadow)) != EOF;) //shadowの中身をtxtにコピー { for(;c != '\n' && c != EOF ;c = fgetc(shadow)) { fputc(c,txt); } fputc('\n',txt); } fclose(shadow); remove(shadow_name); return; }

表示オプション

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