неверное преобразование из 'char' в 'char *' с использованием strcpy - PullRequest
2 голосов
/ 28 сентября 2011

Хорошо, вот части моего кода, с которыми у меня проблемы:

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//

Я получаю ошибку:

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

Проект состоит в том, чтобы создать оболочку psudo OS, которая будет перехватывать и обрабатывать прерывания, а также выполнять основные команды unix. Проблема, с которой я столкнулся, заключается в том, что я должен сохранить последние 20 команд в массив символов, который динамически размещается в стеке. (А также не выделены)

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

char historyArray[20][];

но проблема в том, что он не динамический ...

И да, я знаю, что strcpy должен использоваться для копирования строк.

Любая помощь будет принята с благодарностью!

Ответы [ 7 ]

7 голосов
/ 28 сентября 2011

historyArray указывает на (первый элемент) массив из 20 char с. Вы можете хранить только одну строку в этом массиве.

В C вы можете создать объект char** и указать ему первый элемент массива объектов char*, где каждый элемент указывает на строку. Это то, что делает argv аргумент main().

Но поскольку вы используете C ++, гораздо разумнее использовать vector из string s и позволить библиотеке выполнять управление памятью за вас.

1 голос
/ 28 сентября 2011

Прекратить использование идиом C в программе на C ++:

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();

В результате имеем:

  • Нет угрозы переполнения буфера в readBuffer / getline ()
  • Нет указателей, нигде, чтобы сбить нас с толку.
  • Нет массивов, чтобы перешагнуть через концы
  • произвольно длинные строки ввода
  • Тривиально проверенная семантика выделения памяти
1 голос
/ 28 сентября 2011

Два решения.Во-первых, если вы по какой-то причине действительно хотите использовать массивы, другой более рекомендуется и использует больше «C ++», используя std::string s.

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

// ...

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

Тогда вы можете использовать strcpy для элементов в historyArray.

Рекомендуется второе решение, которое я повторяю (я исправил несколько других вещей):

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;
0 голосов
/ 28 сентября 2011
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//

Но это исправит только ошибки компилятора, а не логические ошибки в коде. Вы используете C ++, поэтому строковое решение:

vector<string> history;

cin.getline(readBuffer,512);

history.push_back(readBuffer);

В качестве альтернативы, если вы хотите одну длинную строку, содержащую все из readBuffer:

string history;

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

Например ...

0 голосов
/ 28 сентября 2011

historyArray [i] является символом.Это один персонаж.Вы хотите использовать жало.Ваша основная проблема в том, что historyArray - это char*, что означает, что он указывает на диапазон памяти, содержащий символы.Вы хотите, чтобы это был char**, который является указателем на указатель на строку.Ваш код инициализации будет

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
}
0 голосов
/ 28 сентября 2011
strcpy(&historyArray[i], &historyArray[i-1]);

Обозначение массива дает ссылки, в то время как strcopy хочет указатели. Преобразование ссылок на указатели с оператором address-of (&).

0 голосов
/ 28 сентября 2011

Ошибка 1: Вы индексируете за пределами своего массива, когда для i установлено значение 20.

Ошибка 2: historyArray [i] является символом, а не символом *.Вам нужен & historyArray [i].

...