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$


コメント