問題1: 本章で作ったcatコマンドを改造して、コマンドライン引数でファイル名が渡されなかったら標準入力を読むようにしなさい。
[root@rhel74 c]# cat mycat.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
static void do_cat(const char *path);
static void die(const char *s);
int
main(int argc, char *argv[]){
int i;
if (argc < 2){
fprintf(stderr, "%s: file name not given\n", argv[0]);
exit(1);
}
for (i = 1; i < argc; i++) {
do_cat(argv[i]);
}
exit(0);
}
#define BUFFER_SIZE 2048
static void
do_cat(const char *path){
int fd;
unsigned char buf[BUFFER_SIZE];
int n;
fd = open(path, O_RDONLY);
if(fd < 0) die(path);
for (;;){
n = read(fd, buf, sizeof buf);
if(n < 0) die(path);
if(n == 0) break;
if(write(STDOUT_FILENO, buf, n) < 0) die(path);
}
if(close(fd) < 0) die(path);
}
static void
die(const char *s){
perror(s);
printf("%s\n",strerror(errno));
exit(1);
}
[root@rhel74 c]# cat mycat2.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
static void do_cat(FILE *f);
int
main(int argc, char *argv[]){
int i;
if (argc == 1){
do_cat(stdin);
} else {
for(i = 1; i < argc; i++){
FILE *f;
f = fopen(argv[i], "r");
if(!f){
perror(argv[i]);
exit(1);
}
do_cat(f);
fclose(f);
}
}
exit(0);
}
static void
do_cat(FILE *f){
int c;
while((c = fgetc(f)) != EOF){
if(putchar(c) < 0) exit(1);
}
}
問題2: バッファ中の'\n'を数えることで、ファイルの行数を出力するコマンドを書きなさい(「wc -l」と同じ機能)。
[root@rhel74 c]# cat wc-l.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
static void die(const char *s);
int
main(int argc, char *argv[])
{
int c;
FILE *f;
int cnt = 0;
f = fopen(argv[1], "r");
if (!f) die(argv[1]);
while ((c = fgetc(f)) != EOF){
if (c == '\n') cnt++;
}
fclose(f);
printf("%d\n",cnt);
exit(0);
}
static void die(const char *s)
{
perror(s);
exit(1);
}
[root@rhel74 c]# ./wc-l /etc/hosts
2