Question

Ok so here are the parts of my code that I'm having trouble with:

char * historyArray;
historyArray = new char [20];

//get input
cin.getline(readBuffer, 512);       
cout << readBuffer <<endl;

//save to history
for(int i = 20; i > 0; i--){
    strcpy(historyArray[i], historyArray[i-1]); //ERROR HERE//  
}

strcpy(historyArray[0], readBuffer); //and here but it's the same error//

The error that i'm receiving is:

"invalid conversion from 'char' to 'char*' 
           initializing argument 1 of 'char* strcpy(char*, const char*)'

The project is to create a psudo OS Shell that will catch and handle interrupts as well as run basic unix commands. The issue that I'm having is that I must store the past 20 commands into a character array that is dynamically allocated on the stack. (And also de-allocated)

When I just use a 2d character array the above code works fine:

char historyArray[20][];

but the problem is that it's not dynamic...

And yes I do know that strcpy is supposed to be used to copy strings.

Any help would be greatly appreciated!

Was it helpful?

Solution

Stop using C idioms in a C++ program:

std::deque<std::string> historyArray;

//get input
std::string readBuffer;
std::getline(std::cin, readBuffer);       
std::cout << readBuffer << std::endl;

//save to history
historyArray.push_front(readBuffer);
if(historyArray.size() > 20)
  historyArray.pop_back();

As a result, we have:

  • No buffer-overflow threat in readBuffer / getline()
  • No pointers, anywhere, to confuse us.
  • No arrays to overstep the ends of
  • Arbitrarily long input strings
  • Trivially-proven memory allocation semantics

OTHER TIPS

historyArray points to (the first element of) an array of 20 chars. You can only store one string in that array.

In C, you could create a char** object and have it point to the first element of an array of char* objects, where each element points to a string. This is what the argv argument to main() does.

But since you're using C++, it makes a lot more sense to use a vector of strings and let the library do the memory management for you.

Two solutions. The first is if you for some reason really want arrays, the other is more recommended and more "C++"ish using std::strings.

char * historyArray[20]; // Create an array of char pointers

// ...

historyArray[i] = new char[SIZE]; // Do this for each element in historyArray

Then you can use strcpy on the elements in historyArray.

Second solution which I repeat is recommended (I've fixed a few other things):

string historyArray[20];

getline(cin, readBuffer); // Make readbuffer an std::string as well
cout << readBuffer << endl;

for(int i = 19; i > 0; i--){ // I think you meant 19 instead of 20
    historyArray[i] = historyArray[i-1];
}

historyArray[0] = readBuffer;

historyArray[i] is a char. It is a single character. You want to use a sting. Your fundemental problem is that historyArray is a char* which means that it points to a memory range containing characters. You want it to be a char** which is a pointer to a pointer to a string. Your initialization code would be

char** historyArray;
historyArray = new char* [20];
for (int i = 0; i < 20; i++)
{
    historyArray[i] = new char [512];  //Big enough to have a 512 char buffer copied in
}

Error 1: You're indexing past your array bounds with i being set to 20.

Error 2: historyArray[i] is a char, not a char *. You need &historyArray[i].

strcpy(&historyArray[i], &historyArray[i-1]);

Array notation gives references while strcopy wants pointers. Convert references to pointers with address-of (&) operator.

char * historyArray;
historyArray = new char [20];

//get input
cin.getline(readBuffer, 512);       
cout << readBuffer <<endl;

//save to history
for(int i = 20; i > 0; i--){
   strcpy(&(historyArray[i]), &(historyArray[i-1])); //ERROR HERE//  
}

strcpy(historyArray, readBuffer); //and here but it's the same error//

But that will only fix the compiler errors, not the logical errors in the code. Your using C++ so the string solution:

vector<string> history;

cin.getline(readBuffer,512);

history.push_back(readBuffer);

Alternatively if you want one long string containing everything from readBuffer:

string history;

cin.getline(readBuffer,512);
history = history += string(readBuffer);

For example...

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top