Чтение из файла в массив *argv[]

Я пытаюсь преобразовать программу Linux на C в DOS. Поскольку командная строка DOS допускает только 128 байт, я пытаюсь прочитать аргументы из файла. В этом файле есть по одной строке для каждого аргумента.

Поэтому я читаю аргументы из файла в массив строк и хочу переопределить адрес * 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]);
}

person Georg    schedule 07.04.2013    source источник
comment
С какой стати ты это делаешь?? Также учтите, что argv имеет фиксированный размер, и если вы не предоставите равное количество байтов, ваша программа может сломаться...   -  person bash.d    schedule 07.04.2013
comment
Почему вы бросаете нулевые указатели? Это не нужно.   -  person autistic    schedule 07.04.2013


Ответы (1)


Есть две вещи, которые вы должны сделать. Во-первых, вам понадобится указатель на указатель на указатель:

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);
}
person Valeri Atamaniouk    schedule 07.04.2013
comment
Я поражен, что вы можете сделать это правильно, не компилируя этот код. - person Georg; 07.04.2013