2013-06-01 42 views
2

最初,这个函数被嵌入到主函数中,创建一个非常混乱的主函数。该程序将使用空格数替换制表符。我仍然对我的函数的参数列表内部以及如何将main中的argc/argv传递给这些函数感到困惑。我做对了吗?我试图分解我的功能,但我不知道如果我做对了

有在文件的顶部部分定义的变量:

#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; 
} 

我需要帮助,是找出在发生的事情函数的参数列表。我认为让我困惑的是如何让我的参数类型匹配,以便我可以将变量从一个函数传递给另一个函数。

+0

函数的存在是在以后的时间重用代码片段。如果你的函数只被调用一次,我认为这可能是一个过早的优化。 –

+5

@Summer_More_More_Tea [编号](http://blog.regehr.org/archives/942) – 2013-06-01 07:23:09

+0

@ H2CO3谢谢,请看看。 –

回答

3

分解不是你最大的问题。相当不小心的错误检查,使用旧的超过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循环 - 这样做仅供练习使用。

+0

所以如果我这样做,那么在主函数中,我将如何将argc和argv传递给detab函数? (因为参数类型不匹配/ detab有三个参数) – Karen

+0

@Karen'void other_function(FILE * inf,FILE * outf,int tabstop)' – 2013-06-01 21:59:40

+0

因此,其他函数只包含while循环吗?但是我遇到的麻烦是main在它的参数列表中只有argc和argv。因此,在主函数内部,当我调用这个其他函数时,我该如何处理其他函数参数列表中的三个参数? – Karen

3

注:这个答案是考虑到问题的早期编辑。它在此期间发生了变化,所以这个答案可能不再相关。

从面向对象的背景来看,我将关注一个叫做Single Responsibility Principle (SRP)的问题。我认为detab(和其他所有函数)应该只做一件特定的事情,但做得很好。正如它的名字所暗示的那样,它并不仅仅是“被剥夺”的;它也有通过main在命令行变量argcargv,将其强加于它提取其实际参数:

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? 
    } 
    … 
} 

这似乎更reaso将所有的命令行验证和价值提取逻辑集中在一个地方,并将其分解在另一个地方;即明确责任界限。不要让一个函数的逻辑溢出到另一个函数中!

对我而言,detab的签名应该看起来更像这个:

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

如果我有两个函数(就像我上面提到的),并且我想调用第二个函数中的第一个函数,那么我将如何构造参数列表?我在尝试匹配参数类型时遇到了麻烦,如果我在顶部定义了那些变量,代码如何更改?谢谢! – Karen

+0

您已将原始问题更改为其他问题。这往往导致以前的答案变得过时,并开始一个开放式问答乒乓球,这不是Stack Overflow应该如何工作。如果你有后续问题,那么请把它作为一个新问题,以便人们不必一遍又一遍地修改他们的答案。谢谢! – stakx

相关问题