Reputation: 146
I have been trying to program a UNIX style shell command prompt in C. Within this program I need it to keep track of the commands that have already been used, so the user can recall the last command by entering 'r'. I made a globally initialized array to hold strings. Whenever the array of characters a user entered needs to be saved, I add it to the global array. I have tried memcpy, simply copying each value using a loop, and just copying the pointer. None of these have been working. I am not super familiar with C and I am sure it is a pointer problem.
Whenever I copy the pointer of inputBuffer to my global array string (it does get copied), however upon leaving the setup function this pointer disappears? I am not exactly sure what I am doing wrong.
Test:
(1)user input --> ls
string[0] = ls
(2)user input --> r
inputBuffer = ls
string[recent] = ls
incorrectly does...
inputBuffer = r
string[recent] = r
(I have included the relevant parts of the code.)
#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 */
}
}
Upvotes: 0
Views: 143
Reputation: 229593
When you "save the input buffer" you actually only store a pointer to the inputBuffer
array:
string[p] = inputBuffer;
The actual data is not copied, you just store a pointer to the global input buffer. When the next input replaces the old content of inputBuffer
, you will see the new content even if you access it through string[recent]
.
The calls to memcpy
don't actually do anything, since the passed input and output buffer all refer to the same memory.
To actually store a copy of the data you have to allocate new memory to store the copy. Since you are dealing with strings, this is most easily done with strdup()
, which duplicates a string:
string[p] = strdup(inputBuffer);
Later, once you are done with such a copy and don't need it anymore you have to free the memory used by the copy:
free(string[p]);
Upvotes: 3
Reputation: 17157
Have you tried changing
char *string[SAVED_BUFFER];
to
char string[SAVED_BUFFER][MAX_LINE];
I think that's how you're treating it in the code
Upvotes: 1