-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcat.c
141 lines (131 loc) · 2.98 KB
/
cat.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
/* trabalho 4: programa cat */
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <limits.h>
#include <unistd.h>
FILE *arq;
int flag[4] = {0}; // option flags
void printOpt(char *buf) {
static int n = 1;
static int flag_s = 0;
int i,len;
char *num;
char *old;
if (flag[3]) { // s option
if (buf[0] == 10) { // buf == '\n'
if (flag_s) {
n++;
return;
} else
flag_s++;
} else {
if (flag_s)
flag_s--;
}
}
if (flag[2]) { // n option
num = malloc(10);
len = sprintf(num,"%d ",n);
n++;
if (!(num = realloc(num,strlen(buf) + len))) {
printf("Realloc error\n");
exit(EXIT_FAILURE);
}
strcat(num,buf);
old = buf;
buf = num;
// free(old);
}
if (flag[0] || flag[1]) { // E option or T option
len = strlen(buf);
for (i = 0; i < len; i++) {
if (buf[i] == 10 && flag[0]) { // '\n'
printf("$");
// printf("%c",buf[i]);
}
if (buf[i] == 9 && flag[1]) { // 'tab'
printf("^I");
} else {
printf("%c",buf[i]);
}
}
} else
printf("%s",buf);
}
void readFile(char const *arg, int f_opt) {
char *file_buf, *buf;
int erro;
file_buf = (char *) malloc(PATH_MAX);
if (!realpath(arg,file_buf)) {
erro = errno;
printf("Error: %s\n",strerror(erro));
exit(EXIT_FAILURE);
}
arq = fopen(file_buf,"r");
if (arq == NULL ) {
erro = errno;
printf("Error: %s\n",strerror(erro));
exit(EXIT_FAILURE);
}
while (!feof(arq)) {
buf = malloc(1024);
if (!buf) {
printf("Malloc error");
exit(EXIT_FAILURE);
}
if (fgets(buf,1024,arq))
if (f_opt) {
printOpt(buf);
} else {
printf("%s",buf);
}
free(buf);
}
}
void sendHelp() {
printf("Program cat.\nDescription: Concatenates the input file(s) and print on the standard output. Default input is keyboard.\nUsage: ./cat [-ETns] [<file> ...]\nOptions:\n -E: Display $ at end of each line\n -T: Display TAB characters as ^I\n -n: number all output lines\n -s: supress repeated empty output lines.\n");
exit(EXIT_FAILURE);
}
void getOut() {
printf("Please type ./cat [-ETns] [<file> ...]\nor type ./cat -h for help.\n");
exit(EXIT_FAILURE);
}
int main(int argc, char * const argv[]) {
int c, i;
int f_opt = 0; // option flag
char buf[2];
while ((c = getopt(argc,argv,"ETnsh")) != -1) {
f_opt++; // turns flag on
switch (c) {
case 'E': flag[0]++; break;
case 'T': flag[1]++; break;
case 'n': flag[2]++; break;
case 's': flag[3]++; break;
case 'h': sendHelp();
case 63: getOut(); // invalid option code
}
}
if (f_opt) { // if there is any option
for (i = 1; (i < argc) && (argv[i][0] == '-'); i++); // set i to use argv[i]
if (argc == i) { // no input file
while (fgets(buf,2,stdin))
printOpt(buf);
} else { // have input file(s)
for (; i < argc; i++)
readFile(argv[i],f_opt);
}
} else { // there is no option
if (argc == 1) {
while (fgets(buf,2,stdin))
printf("%s",buf);
}
if (argc > 1) {
for (i = 1; i < argc ; i++) {
readFile(argv[i],f_opt);
}
}
}
return 0;
}