C言語初心者です。
日本語が記載されている別ファイルを配列に読み込んで、コマンドで操作できるようにしたく
下記のコードを書きました。
現在できているコマンドは下記の通りです。
P :1行前を表示(カーソル移動させる)
N : 1行後を表示(カーソル移動させる)
S : カーソル前後10行を表示(カーソル移動しない)
t : 先頭行へ移動(カーソル移動させる)
l : 最終行を表示(カーソル移動させる)
<実現したいこと>
追加で書きのコマンドを作りたいのですが、うまくいかず困っています。
i :実行画面で文字を入力すると、入力した文字が カーソル行の前に1行挿入される(カーソル移動)
a : カーソル行の後ろに1行挿入(カーソル移動させる)
d : カーソル行を削除したい(カーソルは同じ行に留まる)
r : 実行画面で文字を入力すると、カーソル行を入替えする(カーソルは留まる)
v : 任意のファイル名で保存(オープンしたファイル名がデフォルト)
i,a,dについてはコード書いてみましたが、うまくいきません。
(i,aは文字入力はできるが、2列にわたって文字入力し実行しないと機能していない状態で、
カーソルの移動がうまくいってないようです)
(dについてはアルゴリズム自体違っていると思いますが全く機能していないです)
r,vについては今手付かずになっています。
i,a,dの解決方法について教えていただけたら幸いです。
r,vについても可能であれば実装方法助言いただけないでしょうか。
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <ctype.h> #define GYO 200 //1ファイルの最大行数 #define MOJI 256 //1行の最大文字数 #define LINE line+1 int kansu(char* str,FILE* fp); int main(int argc,char* argv[]) { FILE* fp; char str[GYO][MOJI]; char retsu[128]; int i=0; int line=0;//現在の行番号 int gyo; int k; if(argc==2){ if((fp=fopen(argv[1],"r"))==NULL){ printf("ファイルが開けませんでした\n"); exit(EXIT_FAILURE); } } else{ printf("引数の値が不正です\n"); exit(EXIT_FAILURE); } //strにファイルの内容読込み while(fgets(str[i],MOJI,fp)!=NULL){ //ファイルの行数チェック if(i>GYO){ printf("ファイルの長さが[%d]を超えました",GYO); break; } if(strlen(str[i])==255){ if(kansu(str[i],fp)){ exit(EXIT_FAILURE); } printf("strlen=[%ld]\n",strlen(str[i])); } printf("%d:%s",LINE,str[line]); printf("%ld\n",strlen(str[line])); line++; i++; } line--; int line_max=line;//ファイル全体の行数 while(1){ printf("コマンドを入力してください:"); fgets(retsu,sizeof(retsu),stdin); //大文字も小文字も対応する処理 for(k=0;k<strlen(retsu);k++){ retsu[k]=tolower(retsu[k]); } //nコマンドのため gyo=atoi(retsu); gyo--; //各コマンドの処理 if(strchr(retsu,'o')){ for(int i=0;i<line_max;i++){ if(i==line){ printf("*%d:%s\n",i+1,str[i]); }else{ printf("%d:%s\n",i+1,str[i]); } } printf("line:%d\n",LINE); printf("line_max:%d\n",line_max+1); }else if(strchr(retsu,'d')){ if(line==0){ strcpy(str[line],""); printf("配列削除しました\n"); }else if (line_max==line){ strcpy(str[line],""); line--; line_max--; }else{ for(i=line;0<=(line_max-i);i++){ strcpy(str[i],str[i+1]); } line_max--; } printf("*%d:%s\n",LINE,str[line]); }else if(strchr(retsu,'r')){ if(line<0){ printf("文字列が入っていません\n"); continue; } printf("Enter sentence:"); fgets(str[line],MOJI,stdin); printf("%d:%s\n",LINE,str[line]); continue; }else if(strchr(retsu,'a')){ if(line<0){ printf("文字列が入っていません\n"); continue; } for(int i=line_max; i>=line; i--){ strcpy(str[i+1],str[i]); } line_max++; line++; fgets(str[line],sizeof(str[line]),stdin); printf("*%d:%s\n",LINE,str[line]); continue; }else if(strchr(retsu,'i')){ for(int i=line_max;i>=line;i--){ strcpy(str[i+1],str[i]); } line_max++; fgets(str[line],sizeof(str[line]),stdin); printf("*%d:%s\n",LINE,str[line]); }else if(strchr(retsu,'p')){ if(line<1){ printf("ファイルの先頭です\n"); continue; } line--; printf("*%d:%s\n",LINE,str[line]); }else if(strchr(retsu,'n')){ if(line>line_max){ printf("最端行数を超えました\n"); line=line_max; } line++; printf("*%d:%s\n",LINE,str[line]); continue; }else if(strchr(retsu,'s')){ int p=line-10; if(p<1){ p=1; } int n=line+10; if(n>line_max){ n=line_max; } for(i=p;i<=line;i++){ printf("%d:%s\n",i,str[i-1]); } printf("*%d:%s\n",LINE,str[line]); for(i=line+1;i<n+1;i++){ printf("%d:%s\n",i+1,str[i]); } continue; }else if(strchr(retsu,'f')){ int x; int y; int z; /*配列の数値を交換*/ for(x=0;x<line_max-1;x++){ str[line]=x; for(y=(x+1);y<line_max;y++){ if(str[y]<str[line])line=y; } z=str[line]; str[line]=str[x]; str[x]=z; } if(line>line_max){ printf("入替えできません\n"); } printf("%d:%s\n",LINE,str[line]); continue; }else if (strchr(retsu, 'v')) { char fname[128]; char c2[5]; FILE* wfp; printf("file name is [%s] ?:[y or n]: ", argv[1]); fgets(c2, sizeof(c2), stdin); if (strchr(c2, 'y')) { strcpy(fname, argv[1]); } else if (strchr(c2, 'n')) { printf("Enter file name:"); fgets(fname,sizeof(fname),stdin); } else if(c2[0] == '\n') { continue; } else { printf("Command Error.[%s]\n",c2); continue; } if ((wfp = fopen(fname, "w")) == NULL) { printf("File open Error:w\n"); } for (i=0; i <= line_max; i++) { fprintf(wfp, "%s", str[i]); } fclose(wfp); printf("Write Finish...\n"); continue; }else if(strchr(retsu,'t')){ line=1; printf("%d:%s\n",LINE,str[line]); }else if(strchr(retsu,'l')){ line=line_max; printf("%d:%s\n",LINE,str[line]); printf("linemax=%d\n",line_max+1); }else if(strchr(retsu,'x')){ printf("終了\n"); break; }else if(gyo<=line_max && gyo>=0){ line=gyo; printf("*%d:%s\n",LINE,str[line]); continue; }else{ printf("retsu:%s\n",retsu); printf("line:%d\n",line); printf("コマンドが不正です\n"); continue; } } fclose(fp); exit(EXIT_SUCCESS); } ///関数 int kansu (char* str,FILE* fp) { int i=254; int r=0; printf("str[i]==[%d]\n",(unsigned char)str[i]); printf("str[i]==[%c]\n",(unsigned char)str[i]); printf("str[i]==[0x%x]\n",(unsigned char)str[i]); if((unsigned char)str[i]=='\n' || str[i]=='\0'){ printf("改行、NULLを検知する\n"); return 0; } else if((unsigned char)str[i]>=0 && (unsigned char)str[i]<=127){ printf("00〜7Fに入りました\n"); str[i+1]=10; str[i+2]=0; return 0; } else if((unsigned char)str[i]>=224 && (unsigned char)str[i]<=239){printf("E0〜EFに入りました\n"); str[i]=10; str[i+1]=0; r=fseek(fp,sizeof(char)*-1,SEEK_CUR); if(r){ printf("seekに失敗しました\n"); return -1; } return 0; } else if((unsigned char)str[i]>=128 &&(unsigned char)str[i]<=191){ printf("80~8Fに入りました\n"); if((unsigned char)str[i-1]>=128 &&(unsigned char)str[i-1]<=191){ str[i+1]=10; str[i+2]=0; return 0; } else{ str[i-1]=10; str[i]=0; return 0; r=fseek(fp,sizeof(char)*-2,SEEK_CUR); if(r){ printf("seekに失敗しました\n"); return -1; } return 0; } } else if((unsigned char)str[i]>=224 && (unsigned char)str[i]<=239){ printf("E0〜EFに入りました\n"); str[i+1]=10; str[i+2]=0; return 0; } }
作業環境はLinuxのubuntu上です。
回答3件
あなたの回答
tips
プレビュー