stat関数のことが分かってきたので、自作truncateコマンドもstat関数を使ってきれいにしてみます。
改造前のプログラム。
takk@deb9:~/tmp$ cat -n mytruncate.c 1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <sys/types.h> 4 #include <sys/stat.h> 5 #include <unistd.h> 6 7 int main(int argc, char* argv[]) 8 { 9 FILE *fp; 10 int i,len,size=0; 11 int value=0; 12 int ch,tmp[100]; 13 struct stat buf; 14 15 while ((ch = getopt(argc, argv, "s:v:")) != -1){ 16 switch (ch) { 17 case 's': 18 size = atoi(optarg); 19 break; 20 case 'v': 21 value = atoi(optarg); 22 break; 23 default: 24 printf("parameter error\n"); 25 return 1; 26 } 27 } 28 29 if(optind >= argc){ 30 printf("parameter error\n"); 31 return 1; 32 } 33 34 for(; optind<argc; optind++){ 35 fp = fopen(argv[optind],"r"); 36 if(fp == NULL){ 37 fp = fopen(argv[optind],"w"); 38 for(i=0; i<size; i++) 39 fputc(value,fp); 40 fclose(fp); 41 }else{ 42 stat(argv[optind],&buf); 43 len = buf.st_size; 44 if(len < size){ 45 fp = fopen(argv[optind],"a"); 46 for(i=len; i<size; i++) 47 fputc(value,fp); 48 fclose(fp); 49 }else if(len > size){ 50 truncate(argv[optind],size); 51 } 52 } 53 } 54 return 0; 55 } 56 takk@deb9:~/tmp$
今回statを使って改善する部分です。
34 for(; optind<argc; optind++){ 35 fp = fopen(argv[optind],"r"); 36 if(fp == NULL){ 37 fp = fopen(argv[optind],"w"); 38 for(i=0; i<size; i++) 39 fputc(value,fp); 40 fclose(fp); 41 }else{ 42 stat(argv[optind],&buf); 43 len = buf.st_size; 44 if(len < size){
35行目でfopenして、さらに37行目でfopenしてます。これをstatを使えば、2度同じことをしなくてもよくなります。
35行目のfopenをstatにすると、42行目のstatとかぶってしまいますので、42行目のstatは削除します。
34 for(; optind<argc; optind++){ 35 if(stat(argv[optind],&buf) != 0){ 36 fp = fopen(argv[optind],"w"); 37 for(i=0; i<size; i++) 38 fputc(value,fp); 39 fclose(fp); 40 }else{ 41 len = buf.st_size; 42 if(len < size){
すっきりしました。ビルドして実行。
新規パターン。
takk@deb9:~/tmp$ gcc -o mytruncate mytruncate.c takk@deb9:~/tmp$ ./a.out -s5 -v100 test.bin takk@deb9:~/tmp$ od -tx1 -An test.bin 64 64 64 64 64 takk@deb9:~/tmp$
追加パターン。
takk@deb9:~/tmp$ ./a.out -s12 -v10 test.bin takk@deb9:~/tmp$ od -tx1 -An test.bin 64 64 64 64 64 0a 0a 0a 0a 0a 0a 0a takk@deb9:~/tmp$
削除パターン。
takk@deb9:~/tmp$ ./a.out -s10 test.bin takk@deb9:~/tmp$ od -tx1 -An test.bin 64 64 64 64 64 0a 0a 0a 0a 0a takk@deb9:~/tmp$
上手くいきました。
改造後の全ソースです。
takk@deb9:~/tmp$ cat -n mytruncate.c 1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <sys/types.h> 4 #include <sys/stat.h> 5 #include <unistd.h> 6 7 int main(int argc, char* argv[]) 8 { 9 FILE *fp; 10 int i,len,size=0; 11 int value=0; 12 int ch,tmp[100]; 13 struct stat buf; 14 15 while ((ch = getopt(argc, argv, "s:v:")) != -1){ 16 switch (ch) { 17 case 's': 18 size = atoi(optarg); 19 break; 20 case 'v': 21 value = atoi(optarg); 22 break; 23 default: 24 printf("parameter error\n"); 25 return 1; 26 } 27 } 28 29 if(optind >= argc){ 30 printf("parameter error\n"); 31 return 1; 32 } 33 34 for(; optind<argc; optind++){ 35 if(stat(argv[optind],&buf) != 0){ 36 fp = fopen(argv[optind],"w"); 37 for(i=0; i<size; i++) 38 fputc(value,fp); 39 fclose(fp); 40 }else{ 41 len = buf.st_size; 42 if(len < size){ 43 fp = fopen(argv[optind],"a"); 44 for(i=len; i<size; i++) 45 fputc(value,fp); 46 fclose(fp); 47 }else if(len > size){ 48 truncate(argv[optind],size); 49 } 50 } 51 } 52 return 0; 53 } 54 takk@deb9:~/tmp$
コメント