如何使用带有C中的几个命令的getopt打印输出一次

时间:2015-03-18 07:20:38

标签: c linux unix getopt

我有一个C文件,它读取用户输入并根据各种命令进行打印。

例如,如果我执行./cat -n filename

然后它在每行打印数字

如果我执行./cat -e filename

然后它在每行打印$

到目前为止它的工作正常,但当我同时执行两个命令,如./cat -n -e filename时,它会打印一个文件两次,因为我在两种情况下都保留了printf语句。但是我想只打印一次输出。

这是我的代码

#include<stdio.h>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include <unistd.h>

int main(int argc, char *argv[])
{
    int flag = 0;

    char *cvalue = NULL;
    int index;
    int c;
    char buffer[256];
    int linecount=1;
    opterr = 0;
    FILE *file ;
    while ((c = getopt (argc, argv, "net")) != -1)
        switch (c)
        {
            printf("string %c",c);
          case 'n':

            printf("optind %d",optind);

            for (index = optind; index < argc; index++)
            {
                FILE *file;
                file = fopen(argv[index], "r" );
                //  printf("command %s",argv[1]);
                /* fopen returns 0, the NULL pointer, on failure */
                if(argc<=2)
                {
                    while (fgets(buffer, sizeof(buffer), stdin))
                    {
                        //it will print the user input with number
                        printf("\t %d %s", linecount, buffer);
                        //it will increase the variable by 1
                        linecount++;

                    }
                    printf("\n");
                    linecount=1;
                }

                if ( file == 0 )
                {

                }
                else
                {
                    while (fgets(buffer, sizeof(buffer), file))
                    {
                        //it will print the user input with number
                        printf("\t %d %s", linecount, buffer);
                        //it will increase the variable by 1
                        linecount++;

                    }
                    printf("\n");
                    linecount=1;
                }

            }

            break;
          case 'e':
            for (index = optind; index < argc; index++)
            {
                int x;
                FILE *file;
                file = fopen(argv[index], "r" );
                //  printf("command %s",argv[1]);
                /* fopen returns 0, the NULL pointer, on failure */
                if ( file == 0 )
                {
                }
                else
                {
                    while ((x = fgetc(file)) != EOF)
                    {
                        //it will print the user input
                        if(x =='\n')
                        {
                            //It will add '$' at the end of each line
                            printf("$");
                        }
                        else if(x=='\r')
                        {

                            printf("$^M");
                        }
                        //it will print each line
                        printf("%c",x );
                    }
                }
            }


            break;
          case 't':
            for (index = optind; index < argc; index++)
            {

                FILE *file;
                file = fopen(argv[index], "r" );
                //  printf("command %s",argv[1]);
                /* fopen returns 0, the NULL pointer, on failure */
                if ( file == 0 )
                {
                }
                else
                {
                    while (fgets(buffer, sizeof(buffer), file))
                    {

                        char *str =buffer;
                        while(*str){
                            switch(*str){
                                // case '\v': printf("\\v");break;
                                //  case '\n': printf("\\n"); break;
                              case '\t': printf("^I"); break;

                              default: putchar(*str);break;
                            }
                            str++;
                        }
                        //  printf("%s \n", buffer);


                    }
                }
            }


            break;
          default:
            abort ();
        }

    //printf ("aflag = %d, bflag = %d, cvalue = %s\n",
    // aflag, bflag, optarg);

    // for (index = optind; index < argc; index++)
    //printf ("Non-option argument %s\n", argv[index]);
    getchar();
    return 0;
}

当前输出:

    1 #include<stdio.h>
         2
         3
         4
         5
         6
         7
         8      int main()
         9 {
         10     printf("hello");
         11
         12
         13
         14 getchar();
         15 return 0;
         16 }

#include<stdio.h>$
$
$
$
$
$
$
        int main()$
{$
        printf("hello");$
$
$
$
getchar();$
return 0;$
}$

必需输出:

1  #include<stdio.h>$
     2  $
     3  $
     4  $
     5  $
     6  $
     7  $
     8          int main()$
     9  {$
    10          printf("hello");$
    11  $
    12  $
    13  $
    14  getchar();$
    15  return 0;$
    16  }$

2 个答案:

答案 0 :(得分:2)

您应该将getopt循环与业务逻辑分开。

以下是您可以执行此操作的示例:

int main(int argc, char *argv[])
{
    int flag = 0;

    char *cvalue = NULL;
    int index;
    int c;
    char buffer[256];
    int linecount=1;
    opterr = 0;
    FILE *file;
    int opt_n = 0, opt_e = 0, opt_t = 0;

    while ((c = getopt (argc, argv, "net")) != -1) {
        switch (c)
        {
            printf("string %c",c);
          case 'n':
            opt_n = 1; 
            break;
          case 'e':
            opt_e = 1; 
            break;
          case 't':
            opt_t = 1; 
            break;
        }
    }

    for (index = optind; index < argc; index++) {
        file = fopen(argv[index], "r" );
        if (file == NULL) {
            /* add code to print error message and exit */
        }
        while (fgets(buffer, sizeof(buffer), file))
        {
            if (opt_n) {
                // print line number
                printf("%4d ", linecount);
            }
            if (opt_t) {
                print_t(buffer);  /* you need to create this function */
            } else {
                printf("%s", buffer);
            }
            if (opt_e) {
                printf("$");
            }
            linecount++;
            printf("\n", linecount);
        }
        fclose(file);
    }

    getchar();
    return 0;
}

答案 1 :(得分:2)

正如Paul R评论的那样,首先要检查是否存在这样的标志:

bool eflag = false;
bool nflag = false;
/* ... */

while ((c = getopt (argc, argv, "ent")) != -1) {
        switch (c) {
        case 'n':
                nflag = true;
                break;
        case 'e':
                eflag = true;
                break;
        /* ... */
        default:
                fprintf(stderr, "unknown option %c\n", c);
        }
}

然后你可以处理输入文件,并对你检测到的标志作出反应:

for (index = optind; index < argc; index++) {
        /* cut file opening stuff for brevity */
        while (fgets(buffer, sizeof(buffer), file) {
                if (nflag) {
                        printf("%d", linecount);
                }
                /* the other flags need char-wise processing */
                for (cvalue = *buffer; *cvalue != '\0'; cvalue++) {
                        switch (*cvalue) {
                        case '\n':
                                if (eflag) {
                                        printf("$");
                                }
                                printf("\n");
                                break;
                        /* check other characters */
                        }
                }
        }
}

这样,您可以轻松添加其他标志,或更改您对标志的反应方式。

而且,更重要的是,您只有一次出现文件处理代码。想象一下,你的文件处理有一个错误,在旧的代码中你必须修改它的每一次出现,并且在修复它时可能会忘记一些错误的实例。这样,您只需要修复一次,所有情况都是正确的。

最后,它只输出一次处理过的文件。