2013-06-01 3 views
2

원래이 기능은 주 기능에 포함되어있어 매우 복잡한 기능을 제공한다. 프로그램은 탭을 공백 수로 대체합니다. 나는 아직도 내 함수의 인수 목록에 들어가는 것과 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; 
} 

나는 간다 무엇인지 파악하고, 도움이 필요 무엇 함수의 인수 목록 내가 혼란스럽게 생각하는 것은 내 인수 유형을 일치 시켜서 한 함수에서 다른 함수로 변수를 전달할 수 있다는 것입니다.

+0

기능의 존재는 나중에 코드 조각을 다시 사용하는 것입니다. 함수가 한 번 호출되는 경우, 나는 이것이 성숙한 최적화라고 생각합니다. –

+5

@Summer_More_More_Tea [번호] (http://blog.regehr.org/archives/942) –

+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

그렇다면 main 함수에서 어떻게 detc 함수에 argc와 argv를 전달할 수 있을까요? (인수 유형이 일치하지 않기 때문에/detab에는 3 개의 인수가 있습니다) – Karen

+0

@Karen'void other_function (FILE * inf, FILE * outf, int tabstop) ' –

+0

다른 함수는 while 루프 만 포함 할 수 있도록 하시겠습니까? 하지만 내가 문제가되는 것은 main이 argc와 argv를 인수 목록에만 가지고 있다는 것입니다. 그래서 main 함수 내부에서이 다른 함수를 호출하면 다른 함수의 인수 목록에있는 세 개의 인수를 어떻게 처리합니까? – Karen

3

참고 :이 답변이 질문의 이전 편집 주어졌다. 그 동안 변경되었으므로이 대답은 더 이상 적합하지 않을 수 있습니다. OOP 배경에서 오는

, 나는 Single Responsibility Principle (SRP)로도 알려져 있습니다 하나 개의 문제에 초점을 맞출 것이다. 나는 detab (그리고 다른 모든 기능들)은 단지 하나의 특정한 것을해야한다고 주장하지만 그 일을 잘 수행한다.

그러나 그 이름에서 알 수 있듯이 "detab"하지 않습니다. 명령 줄이기 때문에

detab(argc, argv); 

main이 그 전에 몇 가지 검증을했다 :하지만, 그것은 또한 main하여 강요 한 명령 줄 변수 argcargv에서의 실제 인수를 추출 할 수있다

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에 계속 검증 느낌 (나는 또한 아래의 SRP 위반에 대한 몇 가지 추가 발언을) 모든 명령 줄 유효성 검사 및 값 추출 논리를 한 곳에서 집중시킬 수 있고 다른 곳에서 분리 할 수 ​​있습니다. 즉 책임의 분명한 경계를 이끌어 내십시오. 한 기능의 논리가 다른 기능으로 넘어 가지 않도록하십시오!

나에게있어 detab의 서명은 예를 들어 이 :

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

두 개의 함수 (위에서 쓴 것처럼)가 있고 두 번째 함수의 첫 번째 함수를 호출하려면 어떻게 인수 목록을 구조화할까요? 인수 유형을 일치시키려는 데 문제가 있습니다. 상단에 정의 된 변수가 있으면 코드가 어떻게 변경됩니까? 감사! – Karen

+0

원래 질문을 다른 질문으로 변경했습니다. 이로 인해 이전의 답변이 종종 쓸모 없게되고 개방형 Q & A 핑퐁이 시작됩니다. 스택 오버 플로우가 작동하지 않는 방식입니다. 후속 문제가있는 경우 새로운 질문으로 질문하여 사람들이 여기에서 답변을 반복해서 수정할 필요가 없도록하십시오. 감사! – stakx

관련 문제