2013-04-07 6 views
1

C로 된 Linux 프로그램을 DOS로 변환하려고합니다. DOS 명령 줄에서 128 바이트 만 허용하므로 파일에서 인수를 읽으려고합니다. 이 파일은 각 인수마다 한 행씩 있습니다.파일에서 * argv [] 배열로 읽기

그래서 파일의 인수를 문자열 배열로 읽어 들여 * argv [] 주소를 문자열 배열의 주소로 대체하려고합니다.

하지만 포인터에 대한 포인터와 혼동을 느낍니다. 내 함수의 * argv [] 주소를 제대로 무시하려면 어떻게해야합니까?

이 프로그램은 "argvtest.exe commands.dat"

여기 내 테스트 코드가 호출된다

당신이해야 할 두 가지가 있습니다
#include <stdio.h> 
#include <string.h> 

void read_cmd_file(int *argc,char *argv[]){ 

    if (*argc != 2) return; 

    char buf[256]; 
    char arguments[30][256]; 
    int line_nr=0,i; 

    FILE *fp=(FILE *) NULL; 

    /* open the file */ 
    fp=fopen(argv[1],"r"); 
    if (fp == (FILE *) NULL) 
    { 
     printf("Could not open command file: %s",argv[1]); 
     return; 
    } 

    while (fgets(buf,sizeof(buf)-1,fp) && !feof(fp)) 
    { 

     line_nr++; 
     strcpy(arguments[line_nr],buf); 
     //printf("Argument read: %s\n",buf); 
    } 

    if (fp != (FILE *) NULL) 
     (void) fclose(fp); 

    for (i=1;i<=line_nr;i++) printf("%d,%s\n",i,arguments[i]); 

    *argv=&arguments[0][0]; 
    *argc=line_nr; 

    return; 

} 

int main(int argc,char **argv) 
{ 
    int i; 
    read_cmd_file(&argc,argv); 
    printf("argc=%d\n",argc); 
    for (i=0;i<argc;i++) printf("%d,%s\n",i,argv[i]); 
} 
+0

왜 그런 짓을 했을까? 또한 'argv'는 고정 된 크기를 가지고 있고, 같은 수의 바이트를 제공하지 않으면 프로그램이 깨질 수 있습니다 ... –

+0

왜 널 포인터를 주조합니까? 그건 불필요한 일입니다. – Sebivor

답변

0

. 먼저, 포인터 포인터 포인터를해야합니다 그리고

void read_cmd_file(int *argc,char ***argv) 
{ 
    ... 
    fp=fopen((*argv)[1],"r"); 
    ... 
    *argv = result; 
} 

... 
read_cmd_file(&argc,&argv); 

, 당신은 함수에서 지역 변수에 대한 참조를 반환하려고하지 않을 것이다 : 코드에서

*argv=&arguments[0][0]; 

가 표시입니다 악의를 피하고 사용하지 않아야합니다 ...

대신 함수에서 메모리를 할당 한 다음 사용 후 해제해야합니다. 같은 뭔가 : 지구에

void read_cmd_file(int *argc,char ***argv) 
{ 
    char **arguments; 

    ... 
    arguments = calloc(30, sizeof(*arguments)); // 30 args 
    ... 
    while (fgets(buf,sizeof(buf)-1,fp) && !feof(fp)) 
    { 
     line_nr++; 
     arguments[line_nr] = strdup(buf); // allocates memory on heap 
    } 
    ... 
    *argv=arguments; 
} 

... 
int main(int argc,char **argv) 
{ 
    int i; 
    read_cmd_file(&argc,&argv); 
    for (i=0;i<argc;i++) printf("%d,%s\n",i,argv[i]); 
    ... 
    for (i = 0; i <argc; i++) 
    { 
     free(argv[i]); 
    } 
    free(argv); 
} 
+0

이 코드를 컴파일하지 않으면 올바르게 수행 할 수 있습니다. – Georg

0
void read_cmd_file(int *argc,char *argv[]){ /* you want char ***argv */ 

    if (*argc != 2) return; 

    char buf[256]; 
    char arguments[30][256]; 
    int line_nr=0,i; 
    /* FILE *fp=(FILE *) NULL; No need to assign NULL or cast */ 
    FILE *fp; 
    /* open the file */ 
    fp=fopen(argv[1],"r"); 
    /* if (fp == (FILE *) NULL) No need to cast */ 
    if (fp == NULL) 
    { 
     printf("Could not open command file: %s",argv[1]); 
     return; 
    } 

    /* while (fgets(buf,sizeof(buf)-1,fp) && !feof(fp)) */ 
    /* No need to check feof, also removed -1*/ 
    while (fgets(buf,sizeof(buf),fp)) 
    { 
     line_nr++; 
     strcpy(arguments[line_nr],buf); 
     //printf("Argument read: %s\n",buf); 
    } 

    /* if (fp != (FILE *) NULL) No need to evaluate, it is open */ 
     (void) fclose(fp); 

    for (i=1;i<=line_nr;i++) printf("%d,%s\n",i,arguments[i]); /* change <= to < */ 

    /* Dont do this, you are pointing to the 
     address of a local var (arguments) and returning. 
     Use malloc to allocate arguments */ 
    *argv=&arguments[0][0]; 
    *argc=line_nr; 

    return; 

} 
+0

나는 또한 귀하의 의견을 구현했지만 한 걸릴 수 있습니다. – Georg