Options with getopt

This commit is contained in:
NRZ Code 2025-07-05 13:59:32 -03:00
parent dd4d241152
commit a88c8c04e8

107
paste.c
View file

@ -1,6 +1,8 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <getopt.h>
#include <stdbool.h>
/** /**
* Uso: paste [OPÇÃO]... [ARQUIVO]... * Uso: paste [OPÇÃO]... [ARQUIVO]...
* Escreve linhas constituídas das linhas sequencialmente correspondentes de * Escreve linhas constituídas das linhas sequencialmente correspondentes de
@ -20,40 +22,105 @@
* Documentação completa em <https://www.gnu.org/software/coreutils/paste> * Documentação completa em <https://www.gnu.org/software/coreutils/paste>
* ou disponível localmente via: info "(coreutils) paste invocation" * ou disponível localmente via: info "(coreutils) paste invocation"
*/ */
FILE *openstream(FILE *file, char *str) {
int main(int argc, char **argv) { file = stdin;
int i; if (strcmp(str, "-") != 0)
FILE **files = malloc((argc - 1) * sizeof(FILE *)); file = fopen(str, "r");
char *eofcur = malloc(argc * sizeof(char *)); if (!file) {
char *eofend = malloc(argc * sizeof(char *)); perror(str);
for (i = 0; i < argc-1; i++) { exit(EXIT_FAILURE);
if (strcmp(argv[i+1], "-") == 0)
files[i] = stdin;
else
files[i] = fopen(argv[i+1], "r");
eofcur[i] = '0';
eofend[i] = '1';
} }
char sep = '\t'; return file;
}
int is_endoffiles(char *list) {
for (int i = 0; list[i] != '\0'; i++) {
if (list[i] == '0')
return 0;
}
// str = "111111...";
return 1;
}
/**
* Abertura de arquivos em paralelo
*/
int print_parallel(char **flist, int argc, char sep) {
int i;
char buffer[BUFSIZ]; char buffer[BUFSIZ];
while (strcmp(eofcur, eofend) != 0) { FILE **files = malloc(argc * sizeof(FILE *));
for (i = 0; i < argc-1; i++) { /**
* eofstr = "000000..." (args)
*/
char *eofstr = malloc((argc + 1) * sizeof(char *));
for (i = 0; i < argc; i++) {
files[i] = openstream(files[i], flist[i]);
eofstr[i] = '0';
}
while (!is_endoffiles(eofstr)) {
for (i = 0; i < argc; i++) {
if (fgets(buffer, BUFSIZ, files[i]) == NULL) { if (fgets(buffer, BUFSIZ, files[i]) == NULL) {
strcpy(buffer, "\n"); strcpy(buffer, "\n");
// buffer[0] = '\n'; // buffer[0] = '\n';
// buffer[1] = '\0'; // buffer[1] = '\0';
eofcur[i] = '1'; eofstr[i] = '1';
if (strcmp(eofcur, eofend) == 0) if (is_endoffiles(eofstr))
continue; continue;
} }
if (i < argc-2) if (i < argc-1)
buffer[strcspn(buffer, "\n")] = sep; buffer[strcspn(buffer, "\n")] = sep;
printf("%s", buffer); printf("%s", buffer);
} }
} }
for (i = 0; i < argc-1; i++) { for (i = 0; i < argc; i++) {
fclose(files[i]); fclose(files[i]);
} }
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }
/**
* Abertura de arquivos serial
*/
int print_serial(char **flist, int argc, char sep) {
char buffer[BUFSIZ];
for (int i = 0; i < argc; i++) {
FILE *stream = openstream(stream, flist[i]);
while (fgets(buffer, BUFSIZ, stream) != NULL) {
buffer[strcspn(buffer, "\n")] = sep;
printf("%s", buffer);
}
putchar('\n');
fclose(stream);
}
return EXIT_SUCCESS;
}
int main(int argc, char **argv) {
int opt;
char sep = '\t';
bool mode_serial = false;
while ((opt = getopt(argc, argv, "d:s")) != -1) {
if (opt == 0) {
continue;
}
switch (opt) {
case 'd':
sep = optarg[0];
optind++;
break;
case 's':
mode_serial = true;
break;
default:
abort();
}
}
optind--;
if (mode_serial) {
print_serial(argv + optind, argc - optind, sep);
return EXIT_SUCCESS;
}
print_parallel(argv + optind, argc - optind, sep);
return EXIT_SUCCESS;
}