我正在创建自己的命令提示符(学校项目),我正在尝试跟踪用户使用的最后10个命令。所以我有一个数组:
char* history[10];
从我的理解,这意味着我有一个指针数组,指向字符串。我的问题是我有另一个变量, input 是用户输入。但是每当用户输入新内容时, input 的值都会发生变化,这意味着我的数组中的所有字符串都会更改为用户的新输入。
我想知道如何解决这个问题?
我尝试将我的数组更改为以下内容:
char *history[10][MAX] //Where MAX = 256
我可以改为使用strcpy但我无法弄清楚如何将数组数组输入到方法中,然后使用strcpy将字符串复制到数组数组中。
这是我目前的方法:
char* updateHistory(char *history[], char command[], int histIndex) {
history[histIndex] = command;
return *history;
}
有关其他解决方案的任何帮助或如何使我的解决方案正常运行?
答案 0 :(得分: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]
但是你需要转移更多的数据,这不是那么优雅/有效,或者有一些精心设计的索引系统来跟踪内容
答案 1 :(得分:2)
意味着我的数组中的所有字符串都会更改为用户的新输入。
这可能是因为您有一个command
引用updateHistory
函数内部的变量。因此,无论何时在updateHistory
函数的第一行进行赋值,指针数组中的所有指针都指向相同的内存位置 - command
。
要解决此问题,您需要像这样分配指针数组(例如,您可以在函数外部执行此操作):
char *history[10];
for ( i=0; i < 10; i++ )
{
history[i] = malloc(MAXLEN);
}
然后复制字符串(这可以进入你的函数):
strcpy(history[i], command);
另外,最后不要忘记free
数组中的每个变量。
答案 2 :(得分: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
从静态声明的数组中获得的好处是对阵列存储的自动内存管理以及从堆栈分配的内存中的效率略有好处。要么这样做,只需要管理多少信息。
答案 3 :(得分:0)
如果要将指针数组传递给函数,则可以使用'&amp;'在调用函数时签名以传递地址
例如:
这就是你声明的数组char* history[10];
这是您使用的功能:
char* updateHistory(char *history[], char command[], int histIndex) {
history[histIndex] = command;
return *history;
}
因此,在main()
正文中调用函数时,请将其称为
main()
{
updateHistory(&history, command, histIndex);
}
我希望这会帮助你..好吧。