簡體   English   中英

我嘗試分解函數,但是不確定是否做對了

[英]I tried decomposing my function, but I'm not sure if I did it right

最初,此功能已嵌入到main函數中,從而創建了一個非常混亂的main函數。 該程序用空格數替換制表符。 對於函數的參數列表中的內容以及如何將argc / argv從main傳遞到這些函數中,我仍然感到困惑。 我這樣做對嗎?

文件頂部有一些已定義的變量:

#define OUTFILE_NAME "detabbed"
#define TAB_STOP_SIZE 8
#define NUM_ARGS 2
#define FILE_ARG_IDX 1

這是我第二次嘗試:

void open_file(FILE *inf, FILE *outf, char *in[]) /*I feel like the arguments aren't right  
{                                                   and this function is just opening
                                                    and reading files*/ 
   inf = fopen(in[1], "r");
   outf = fopen(OUTFILE_NAME, "w");

   if (inf == NULL)
   {
      perror(in[1]);
      exit(1);
   }

   else if (outf == NULL)
   {
      perror(OUTFILE_NAME);
      exit(1);
   }

   fclose(inf);
   fclose(outf);
}

void detab(FILE *infile, FILE *outfile, char *argument[]) /* Confused about argument list
{                                                           and this function actually
   char c;                                                  does the detabbing */
   int character_count = 0, i, num_spaces;

   open_file(infile, outfile, argument);                 /* I want to call the previous
                                                          function but again, confused
   while (fscanf(infile, "%c", &c) != EOF)                about the argument list */
   {
      if (c == '\t')
      {
         num_spaces = TAB_STOP_SIZE - (character_count % TAB_STOP_SIZE);

         for (i = 0; i < num_spaces; i++)
         {
            fprintf(outfile, " ");
         }

         character_count += num_spaces;
      }
      else if (c == '\n')
      {

         fprintf(outfile, "\n");
         character_count = 0;
      }
      else
      {
         fprintf(outfile, "%c", c);
         character_count++;
      }
   }

}

int main(int argc, char *argv[])
{
   if (argc < 1)
   {
      fprintf(stderr, "usage: prog file\n");
      exit(1);
   }

   else if (argc < NUM_ARGS)
   {
      fprintf(stderr, "usage: %s file\n", argv[0]);
      exit(1);
   }

   detab(argc, argv);   /* I want to pass argc and argv to the detab function, but I'm
                          having trouble with the argument list */
   return 0;
}

我需要幫助的是弄清楚函數參數列表中的內容。 我認為讓我感到困惑的是如何使我的參數類型匹配,以便我可以將變量從一個函數傳遞給另一個函數。

分解不是您最大的問題。 相當粗心的錯誤檢查,使用舊的超重fscanf()fprintf()以及全局變量。 此外,輸入文件名中缺少const正確性,變量名過長和冗長,以及您對+=++運算符的不了解僅是加分項。 我想這就是為什么您的代碼看起來過分膨脹(實際上是這樣)的原因。

我將這樣重寫函數:

void detab(const char *in, const char *out, int tabstop)
{
    FILE *inf = fopen(in, "r");
    if (!inf) return;

    FILE *outf = fopen(out, "w");
    if (!outf) {
        fclose(inf);
        return;
    }

    int n = 0;
    int c;
    while ((c = fgetc(inf)) != EOF) {
        if (c == '\t') {
            int pad = tabstop - n % tabstop;

            for (int i = 0; i < pad; i++)
                fputc(' ', outf);

            n += pad;
        } else if (c == '\n') {
            fputc('\n', outf);
            n = 0;
        } else {
            fputc(c, outf);
            n++;
        }
    }

    fclose(inf);
    fclose(outf);
}

如果要進一步分解,則可以編寫一個函數,該函數使用兩個FILE *和制表位作為其參數,並且僅包含while循環-練習時留給您。

注意:此答案是對問題的早期編輯。 同時,它已經更改,因此該答案似乎不再有意義。

來自OOP背景,我將集中討論一個單一問題,即單一責任原則(SRP) 我認為detab (以及其他所有功能)應該只做一件特定的事情 ,但是要做好那件事。

但是,它不僅僅顧名思義就是“去刺”。 它也有在命令行變量提取其實際參數argcargv ,這是由在它迫使main

detab(argc, argv);

main在此之前已經進行了一些驗證,但是由於僅將命令行傳遞給了函數,因此您顯然感覺像是在detab繼續驗證(我也對違反以下SRP提出了一些補充意見):

void detab(int arg_list, char *array[]) // why ask for arg_list if you don't need it?
{
   …
   infile = fopen(array[1], "r"); // not obvious to caller that only array[1] is relevant 
   …
   if (infile == NULL)
   {
      perror(array[1]);
      exit(1); // should your function really have the power to terminate the program?
   }
   …
}

將所有命令行驗證和值提取邏輯集中在一個地方,將取消標記集中在另一個地方似乎更加合理。 也就是說,划清責任界限。 不要讓一個功能的邏輯溢出到另一個功能中!

在我看來, detab的簽名應該更像這樣:

void detab(FILE *in, FILE *out);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM