2016-02-05 6 views
4

Я создаю собственное командное приглашение (школьный проект), и я пытаюсь отслеживать последние 10 команд, которые пользователь использует. Таким образом, у меня есть массив:Как передать массив char в функцию в C

char* history[10]; 

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

Мне интересно, как я могу обойти это?

Я попытался изменить свой массив следующим образом:

char *history[10][MAX] //Where MAX = 256 

Где я мог бы использовать вместо зЬгсра, но вместо этого я не мог понять, как ввести массив массивов в метод, а затем использовать STRCPY для скопируйте строку в массив массивов.

Вот мой текущий метод:

char* updateHistory(char *history[], char command[], int histIndex) { 
    history[histIndex] = command;  
    return *history; 
} 

Любая помощь по другому решению, или как получить мое решение работает?

+0

- MAX, представляющий максимальные символы в одной команде? – Pooya

+0

Какой смысл возвращать 'return * history;'? –

ответ

2

Значение всех строк в моем массиве изменяется на новый вход пользователя.

Это происходит, вероятно, потому, что у вас есть одна переменная, в которой command относится к внутренней updateHistory функции. Поэтому в любое время, когда вы выполняете назначение в первой строке функции updateHistory, все указатели в вашем массиве указателей указывают на то же место в памяти - command.

Чтобы это исправить, необходимо выделить свой массив указателей, как это (например, вы можете сделать это за пределами вашей функции):

char *history[10]; 
for (i=0; i < 10; i++) 
{ 
    history[i] = malloc(MAXLEN); 
} 

Затем скопировать строку (это может пойти внутри функции):

strcpy(history[i], command); 

Также не забудьте free каждой переменной в массиве, в конце концов.

+1

Благодарим вас за ответ. Казалось, что это было проще всего, и быстро и эффективно решает мою проблему. – Logan

+0

@ Anon Рад, если это помогло –

3

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

Так что-то подобное должно работать

#define MAX_HISTORY 10 

char* history[MAX_HISTORY]; 

if (fgets(input, sizeof(input), stdin) != NULL) 
{ 
    input[strlen(input)-1] = '\0'; // remove \n 
    history[n++] = strdup(input); // allocates and copies the input string 
    if (n == MAX_HISTORY) 
    { 
    // throw away the oldest and move pointers forward one step 
    } 
} 

strdup концептуально так же, как

malloc() + strcpy() 

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

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

char history[MAX_HISTORY][MAX_CMD_LEN] но тогда вам нужно будет перенести больше данных, и это не так элегантно/эффективно или иметь некоторые разработать систему индексирования для отслеживания содержания

0

Если вы хотите передать массив указателя на функцию, вы можете использовать знак «&», чтобы передать адрес при вызове функции.
Например:
Это то, что вы объявили массив char* history[10];
Это функция, которую вы использовали:

char* updateHistory(char *history[], char command[], int histIndex) { 
    history[histIndex] = command;  
    return *history; 
} 

Таким образом, при вызове функции в теле main(), назовем его так

main() 
{ 
updateHistory(&history, command, histIndex); 
} 

Надеюсь, это поможет вам. ОК.

1

В то время как вы свободны выделять пространство в куче malloc или calloc, если вы ограничиваете свою историю разумным размером, простой 2D статически объявленный массив символов может работать одинаково хорошо. Например:

#include <stdio.h> 
#include <string.h> 

/* constants for max pointers, max chars */ 
enum {MAXP = 10, MAXC = 256}; 

int main (void) { 

    char history[MAXP][MAXC] = {{0}}; 
    char buf[MAXC] = {0}; 
    size_t i, n = 0; 

    while (printf ("prompt > ") && fgets (buf, MAXC, stdin)) { 
     size_t buflen = strlen (buf); 
     buf[--buflen] = 0; /* strip newline */ 

     /* check buflen to prevent saving empty strings */ 
     if (!buflen) continue; 

     strncpy (history[n++], buf, buflen); 

     if (n == MAXP) /* handle full history */ 
      break; 
    } 

    for (i = 0; i < n; i++) 
     printf (" history[%zu] : %s\n", i, history[i]); 

    return 0; 
} 

Пример использование/вывод

$ ./bin/fgets_static2d_hist 
prompt > ls -al 
prompt > mv a b/foo.txt 
prompt > rsync ~/tmp/xfer hostb:~/tmp 
prompt > du -hcs 
prompt > cat /proc/cpuinfo 
prompt > grep buflen * 
prompt > ls -rt debug 
prompt > gcc -Wall -Wextra -Ofast -o bin/fgets_static2d_hist fgets_static2d_hist.c 
prompt > objdump obj/fgets_static2d.obj 
prompt > source-highlight -i fgets_static2d.c -o fgets_static2d.html 
history[0] : ls -al 
history[1] : mv a b/foo.txt 
history[2] : rsync ~/tmp/xfer hostb:~/tmp 
history[3] : du -hcs 
history[4] : cat /proc/cpuinfo 
history[5] : grep buflen * 
history[6] : ls -rt debug 
history[7] : gcc -Wall -Wextra -Ofast -o bin/fgets_static2d_hist fgets_static2d_hist.c 
history[8] : objdump obj/fgets_static2d.obj 
history[9] : source-highlight -i fgets_static2d.c -o fgets_static2d.html 

Выгоды вы получаете от статический объявленного массива автоматического управления памятью вашего хранения массива и небольшое преимущество в эффективности из памяти, выделенных из стека. Либо это сделает, это просто вопрос того, сколько информации вы управляете.

Смежные вопросы