C 文本转换程序

C Text conversion program

我是 C 语言的新手,一直在开发一个程序,该程序接受文本文件或键盘输入,并将所有字母转换为大写、小写,或将它们旋转 13 个位置,具体取决于用户给出的输入应该是这样的:./tconv -u test.txt 理论上,这应该将 test.txt 中的所有字母都变成大写字母。如果没有给出文件,./tconv -u,那么它应该从键盘输入。

我想我遗漏了一些相当简单的东西,但是当我 运行 它带有任何 -r、-u 或 -l 参数时,它说它无法读取“-r”、“-u” ,或“-l”。我错过了什么?

#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>

FILE*
input_from_args(int argc, const char *argv[])
{
  if (argc==1){
    return stdin;
  }else{
    return fopen(argv[1],"r");
  }
}

int
rot13(c)
{
  int e;
  int ROT;
  ROT = 13;
  if(c>='A' && c <='Z'){
    if((e=c+ROT)<='Z')
      return e;
    else{
      e = c - ROT;
      return e;
    }
  }
  else{
    return c;
  }
}

int
main(int argc, const char*argv[])
{
  FILE *src = input_from_args(argc,argv);
  FILE *dest = stdout;
  if (src == NULL){
    fprintf(stderr, "%s: unable to open %s\n", argv[0], argv[1]);
    exit(EXIT_FAILURE);
  }
  char *rotate = "-r";
  char *lower = "-l";
  char *upper = "-u";
  int i;
  i =0;
  int ch;
while ((ch = fgetc(src))!=EOF){
    if (strcmp(upper,argv[i])==0){
      fprintf(dest,"%c",toupper(ch));
    }
    else if (strcmp(lower,argv[i])==0){
      fprintf(dest,"%c",tolower(ch));
    }
    else if (strcmp(rotate,argv[i])==0){
      fprintf(dest,"%c",rot13(ch));
    }
    else{
      fprintf(dest,"%c",ch);
    }
  }
  fclose(src);
  return EXIT_SUCCESS;
}

Argv[0] 是您的程序,argv[1] 是您的标志,argv[2] 是文件名(如果您提供的话)。您正在尝试打开 argv[1] 名为“-r”的文件

如果您使用的是 linux 平台,您可以查看 getopt_long to parse the command line options. it is provided by GNU for linux systems and it is system dependent. For system independent command line parsing Google gflags

这将有助于减少命令行解析的开销,您可以更专注于程序逻辑。

这是取自 http://www.gnu.org/software/libc/manual/html_node/Getopt-Long-Option-Example.html

的示例
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>

/* Flag set by ‘--verbose’. */
static int verbose_flag;

int
main (int argc, char **argv)
{
  int c;

  while (1)
    {
      static struct option long_options[] =
        {
          /* These options set a flag. */
          {"verbose", no_argument,       &verbose_flag, 1},
          {"brief",   no_argument,       &verbose_flag, 0},
          /* These options don’t set a flag.
             We distinguish them by their indices. */
          {"add",     no_argument,       0, 'a'},
          {"append",  no_argument,       0, 'b'},
          {"delete",  required_argument, 0, 'd'},
          {"create",  required_argument, 0, 'c'},
          {"file",    required_argument, 0, 'f'},
          {0, 0, 0, 0}
        };
      /* getopt_long stores the option index here. */
      int option_index = 0;

      c = getopt_long (argc, argv, "abc:d:f:",
                       long_options, &option_index);

      /* Detect the end of the options. */
      if (c == -1)
        break;

      switch (c)
        {
        case 0:
          /* If this option set a flag, do nothing else now. */
          if (long_options[option_index].flag != 0)
            break;
          printf ("option %s", long_options[option_index].name);
          if (optarg)
            printf (" with arg %s", optarg);
          printf ("\n");
          break;

        case 'a':
          puts ("option -a\n");
          break;

        case 'b':
          puts ("option -b\n");
          break;

        case 'c':
          printf ("option -c with value `%s'\n", optarg);
          break;

        case 'd':
          printf ("option -d with value `%s'\n", optarg);
          break;

        case 'f':
          printf ("option -f with value `%s'\n", optarg);
          break;

        case '?':
          /* getopt_long already printed an error message. */
          break;

        default:
          abort ();
        }
    }

  /* Instead of reporting ‘--verbose’
     and ‘--brief’ as they are encountered,
     we report the final status resulting from them. */
  if (verbose_flag)
    puts ("verbose flag is set");

  /* Print any remaining command line arguments (not options). */
  if (optind < argc)
    {
      printf ("non-option ARGV-elements: ");
      while (optind < argc)
        printf ("%s ", argv[optind++]);
      putchar ('\n');
    }

  exit (0);
}