Массивы в хлопотах - PullRequest
       3

Массивы в хлопотах

0 голосов
/ 26 ноября 2011

Я пытался запрограммировать командную строку оболочки в стиле UNIX на C. В этой программе мне нужно отслеживать команды, которые уже были использованы, чтобы пользователь мог вызвать последнюю команду, введя «r». Я сделал глобально инициализированный массив для хранения строк. Всякий раз, когда необходимо сохранить массив символов, введенный пользователем, я добавляю его в глобальный массив. Я пробовал memcpy, просто копируя каждое значение, используя цикл, и просто копируя указатель. Ни один из них не работал. Я не очень знаком с C, и я уверен, что это проблема указателя.

Всякий раз, когда я копирую указатель inputBuffer в строку глобального массива (она копируется), однако после выхода из функции настройки этот указатель исчезает? Я не совсем уверен, что я делаю неправильно.

Тест:

(1) пользовательский ввод -> ls

string [0] = ls

(2) пользовательский ввод -> r

inputBuffer = ls

строка [недавний] = ls

неправильно делает ...

inputBuffer = r

строка [недавний] = г

(я включил соответствующие части кода.)

 #define MAX_LINE 80 /* 80 chars per line, per command, should be enough. */
    #define SAVED_BUFFER 100


    char *string[SAVED_BUFFER];
    int p = 0;
    int recent = -1;
    int stringSize = 0;

    void setup(char inputBuffer[], char *args[],int *background)
    {
        int length, /* # of characters in the command line *

        /* read what the user enters on the command line */
        length = read(STDIN_FILENO, inputBuffer, MAX_LINE);  

        start = -1;
        if (length == 0)
            exit(0);            /* ^d was entered, end of user command stream */
        if (length < 0){
            perror("error reading the command");
            exit(-1);           /* terminate with error code of -1 */
        }

        if (inputBuffer[0] == 'r' && inputBuffer[1] == '\n' && stringSize > 0) {
            int k;  

            memcpy(inputBuffer, string[recent], strlen(string[recent]) + 1);
            printf("%s",inputBuffer);
            printf("%s",string[recent]);

        }
        else {  

            string[p] = inputBuffer;
            printf("%s", string[0]);

            stringSize++;
            recent++; // one behind strings current array location, to get history
            p++; // current string array spot
        }

    }

    int main(void)
    {
        char inputBuffer[MAX_LINE]; /* buffer to hold the command entered */
        int background;             /* equals 1 if a command is followed by '&' */
        char *args[MAX_LINE/2+1];/* command line (of 80) has max of 40 arguments */


        while (1) {            /* Program terminates normally inside setup */
        background = 0;
        printf("COMMAND2->");

            fflush(0);

        setup(inputBuffer, args, &background);       /* get next command */
        }
    }

Ответы [ 2 ]

3 голосов
/ 26 ноября 2011

Когда вы «сохраняете входной буфер», вы фактически сохраняете только указатель на массив inputBuffer:

string[p] = inputBuffer;

Фактические данные не копируются, вы просто сохраняете указатель на глобальный буфер ввода. Когда следующий вход заменит старый контент inputBuffer, вы увидите новый контент, даже если вы получите к нему доступ через string[recent].

Вызовы memcpy на самом деле ничего не делают, поскольку переданный входной и выходной буфер ссылаются на одну и ту же память.

Чтобы фактически сохранить копию данных, вам нужно выделить новую память для хранения копии. Поскольку вы имеете дело со строками, это проще всего сделать с помощью strdup(), который дублирует строку:

string[p] = strdup(inputBuffer);

Позже, как только вы закончили с такой копией, и она вам больше не нужна, вы должны освободить память, используемую копией:

free(string[p]);
1 голос
/ 26 ноября 2011

Вы пытались изменить

char *string[SAVED_BUFFER];

на

char string[SAVED_BUFFER][MAX_LINE];

Я думаю, что именно так вы относитесь к этому в коде

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...