問題1: タブ文字('\t')を「\t」という2文字、改行を「'$'+改行」の2文字として置き換えながら出力するcatコマンドを書きなさい。
[root@rhel74 c]# cat mycat3.c
#include <stdio.h>
#include <stdlib.h>
int
main()
{
int c;
while((c = getchar()) != EOF) {
if (c == '\t'){
printf("%s","\\t");
} else if (c == '\n') {
printf("%s\n","$");
} else {
if (putchar(c) < 0) exit(1);
}
}
exit(0);
}
[root@rhel74 c]# cat test.txt | ./mycat3
tab ->\t<- tab $ ->$
tab ->\t<- tab $ ->$
tab ->\t<- tab $ ->[root@rhel74 c]#
問題2: stdio APIを使ってファイルを読み込み、その行数を出力するコマンドを書きなさい(「wc -l」と同じ機能)。ファイル末尾に'\n'がない場合にも対応しましょう。
[root@rhel74 c]# cat wc-l2.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;
int oldc;
FILE *f;
int cnt = 0;
f = fopen(argv[1], "r");
if (!f) die(argv[1]);
while ((c = fgetc(f)) != EOF){
if (c == '\n') cnt++;
oldc = c;
}
if ( oldc != '\n') cnt++;
fclose(f);
printf("%d\n",cnt);
exit(0);
}
static void die(const char *s)
{
perror(s);
exit(1);
}
[root@rhel74 c]# ./wc-l2 ./test.txt
3
[root@rhel74 c]# cat ./test.txt
tab -> <- tab $ ->
tab -> <- tab $ ->
tab -> <- tab $ ->[root@rhel74 c]#
問題3: fread()とfwrite()を使ってcatコマンドを書きなさい。
[root@rhel74 c]# cat mycat4.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int
main(int argc, char *argv[])
{
char buf[2048];
FILE *f;
f = fopen(argv[1], "r");
for (;;){
size_t size = fread(buf, 1, sizeof buf, f);
if(size < sizeof buf){
if(ferror(f)) puts("ferror");
}
size_t ret = fwrite(buf, 1, size, stdout);
if(ret < size) puts("fwrite error");
if(ret < sizeof buf) break;
}
if(fclose(f) != 0) puts("fclose error");
return 0;
}
[root@rhel74 c]# ./mycat4 /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6