/* * Sample answer * Author: Programming C teaching group * Date: 2026/10/15 */ #include #include #include #define MAXLEN 1024 int main(){ int i; char c; FILE *fp; char buffer[MAXLEN]; char query[MAXLEN]; char buffer_prev[MAXLEN]; int status; int arg1, arg2; int in_len, buf_len; /* ファイルのオープン */ fp = fopen("myedit_in.txt", "r"); if(fp == NULL){ printf("Cannot open input file.\n"); exit(1); } /* データの読み出し(最後に'\0'を忘れないこと) */ buf_len = 0; while(1){ c = fgetc(fp); if(c == EOF){ buffer[buf_len++] = '\0'; break; } else{ buffer[buf_len++] = c; } } fclose(fp); /* コマンド入力のためのループ */ while(1){ status = scanf("%s", query); if(status != 1) break; /* 現在のテキストの長さを取得する */ buf_len = strlen(buffer); /* それぞれのコマンドのチェック */ if(strcmp("print", query) == 0){ /* printコマンド */ printf("%s", buffer); continue; } else if(strcmp("insert", query) == 0){ /* insertコマンド */ if(scanf("%d %s", &arg1, query) == 2){ /* undoコマンド用の変更前バッファ保持 */ strcpy(buffer_prev, buffer); /* insertコマンドは演習問題5と同じ考え方で実装できる */ /* 入力と元データの文字列の長さを得る */ in_len = strlen(query); /* バッファの後端挿入かどうかチェック */ if(arg1 < 0) arg1 = buf_len; /* '\0' を含めてBUFSIZEを越えたらエラー */ /* 保持している文字列よりも後ろに挿入しようとしたらエラー */ if(buf_len + in_len + 1 > MAXLEN || arg1 > buf_len){ printf("ERROR\n"); exit(1); } /* 入力のデータの長さ分,元データの文字を後ろに移動する */ for(i = buf_len; i >= arg1; i--){ buffer[i + in_len] = buffer[i]; } /* 空けた部分に入力した文字を入れる */ for(i = 0; i < in_len; i++){ buffer[arg1 + i] = query[i]; } continue; } } else if(strcmp("quit", query) == 0){ /* quitコマンド */ /* ファイルのオープン */ fp = fopen("myedit_out.txt", "w"); if(fp == NULL){ printf("Cannot open output file.\n"); exit(1); } /* データの書き出し(最後の'\0'は出力しないこと) */ i = 0; while(buffer[i] != '\0'){ fputc(buffer[i], fp); i++; } /* ファイルのクローズ */ fclose(fp); exit(0); } else if(strcmp("space", query) == 0){ /* spaceコマンド */ if(scanf("%d", &arg1) == 1){ /* undoコマンド用の変更前バッファ保持 */ strcpy(buffer_prev, buffer); /* バッファの後端挿入かどうかチェック */ if(arg1 < 0) arg1 = buf_len; /* バッファサイズの確認 */ if(buf_len + 1 >= MAXLEN || arg1 > buf_len){ printf("ERROR\n"); exit(1); } /* 一文字分バッファをずらして空白を挿入 */ for(i = buf_len; i >= arg1; i--){ buffer[i + 1] = buffer[i]; } buffer[arg1] = ' '; continue; } } else if(strcmp("enter", query) == 0){ /* enterコマンド */ if(scanf("%d", &arg1) == 1){ /* undoコマンド用の変更前バッファ保持 */ strcpy(buffer_prev, buffer); /* バッファの後端挿入かどうかチェック */ if(arg1 < 0) arg1 = buf_len; /* バッファサイズの確認 */ if(buf_len + 1 >= MAXLEN || arg1 > buf_len){ printf("ERROR\n"); exit(1); } /* 一文字分バッファをずらして空白を挿入 */ for(i = buf_len; i >= arg1; i--){ buffer[i + 1] = buffer[i]; } buffer[arg1] = '\n'; continue; } } else if(strcmp("cut", query) == 0){ /* cutコマンド */ if(scanf("%d %d", &arg1, &arg2) == 2){ /* undoコマンド用の変更前バッファ保持 */ strcpy(buffer_prev, buffer); /* 現在のバッファの長さを超えて削除しようとしたらエラー */ if(arg1 + arg2 - 1 > buf_len || arg2 < 0 || arg1 < 0){ printf("ERROR\n"); exit(1); } /* 削除する分だけ文字を詰める('\0'があるので注意) */ for(i = arg1 - 1; i < buf_len - arg2 + 1; i++){ buffer[i] = buffer[i + arg2]; } continue; } } else if(strcmp("undo", query) == 0){ /* undoコマンド */ strcpy(buffer, buffer_prev); continue; } /* 該当するコマンドが見付からないとき */ printf("ERROR\n"); exit(1); } return 0; }