Как я могу напечатать содержимое стандартного файла или файла без смежных пустых строк? - PullRequest
1 голос
/ 08 апреля 2019

Я хочу скопировать опцию -s команды cat linux.Он в основном удаляет каждую пустую строку рядом с другой, делая вывод одинаково разнесенным.Как я могу подойти к этому без создания временного файла?

Вот моя команда cat:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <ctype.h>
#include <getopt.h>
#define BUF_SIZE 1024

void formattedLineout(int *index, char buffer[]){
  printf ("     %d\t%s", *index, buffer);
  (*index)++;
}

void bprint(int *index, char buffer[]){
  if (strcmp(buffer,"\n") == 0){
    printf (" %s", buffer);
  }
  else {
    formattedLineout(index, buffer);
  }
}

void outputLine(int *index, char buffer[], int bflag, int nflag){
  if (nflag){
    formattedLineout(index, buffer);
  }
  else if (bflag){
    bprint(index, buffer);
  }
  else{
    printf("%s", buffer);
  }
}

int readStdin(int index, int bflag, int nflag){
  char buffer[BUF_SIZE];
  while(fgets(buffer, BUF_SIZE, stdin)){ //reads from the standard input and prints the input
    outputLine(&index, buffer, bflag, nflag);
  }
  return index; //returns the incremented index to perpetuate its use
}

int readFile(char* filename, FILE* fp, int index, int bflag, int nflag){
  char s[BUF_SIZE];
  if (fp==NULL){ //in case the file doesn't exist
    printf("%s: No such file or directory\n", filename);
    exit(1);
  }
  while ((fgets(s, BUF_SIZE, fp))){ //printing loop
    outputLine(&index, s, bflag, nflag);
  }
  return index;
}

void readArgs(int argc, char* argv[], int bflag, int nflag){
  FILE* fp;
  int index = 1; //line index. to be used in case -b or -n is passed as an argument

  if (bflag == 1 && nflag == 1){ //if -b and -n are passed as argument, b overrides n
    nflag = 0;
  }

  for (int i=optind; i<argc; i++){
    if (*argv[i] == '-'){ //in case of '-' in argv[i], reads from stdin and prints
      index = readStdin(index, bflag, nflag);
      clearerr(stdin);
    }
    else { //prints the contents of the file in *argv[i]
      fp = fopen(argv[i], "r");
      index = readFile(argv[i], fp, index, bflag, nflag);
      fclose(fp);
    }
  }
}

int main(int argc, char* argv[]){
  int option; //option passed as argument
  int bflag = 0; //-b option deactivated by default
  int nflag = 0; //-n option deactivated by default
  opterr = 0; //deactivates getopt's default error messages

  //checks if there are options passed as argument and updates their flags
  while ((option = getopt(argc, argv, "bn")) != -1){
    switch (option){
      case 'b':
              bflag = 1;
              break;
      case 'n':
              nflag = 1;
              break;
      case '?': //in case there was some problem
              exit(1);
    }
  }

  if (argc<2 || optind == argc){ //if there are no arguments or if there are only options
    readStdin(1,0,0);
    return 0;
  }
  readArgs(argc, argv, bflag, nflag); //otherwise
  return 0;
}

Я хочу иметь возможность смешивать эту функциональность с другими опциями, которые я реализовал (например, -n и -b).

Любое предложение?

1 Ответ

0 голосов
/ 08 апреля 2019

Параметры: linux LF, а не linux CRLF пропустить пробел, чтобы пропустить пробел в пустых строках

void skip(int skipw, int linux)
{
    int count = 0;
    int ch;
    while((ch = fgetc(stdin)) != EOF)
    {
        if((ch == '\r' && !linux) || ch == '\n')
        {
            if(count <= (!linux * 2))
            { 
                count++;
                printf("%c", ch);    
            }
        }
        else
        {
            if(skipw && isspace(ch)) continue;
            count = 0;
            printf("%c", ch);
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...