Преобразование массива строк в символ, кратный char * [] - PullRequest
0 голосов
/ 13 марта 2019

У меня есть следующий фрагмент кода:

#include <iostream>
#include <string>
using namespace std;

int main(){
    string text;
    string * OldArray = nullptr;
    string * NewArray = nullptr;
    unsigned int counter = 0;

    cout <<"Enter StringS" <<endl;
    while(true){
        cin >> text;
        if (text.find("End") != string::npos ) break;
        NewArray = new string[counter +1];
        for(int i = 0; i < counter; i++){
            NewArray[i] = OldArray[i];
        }
        NewArray[counter] = text;
        delete [] OldArray;
        OldArray = NewArray;
        counter++;
    }

    for (int i = 0; i< counter; i++){
        cout << OldArray[i];
    }

    return 0;
}

И я должен написать код, который делает то же самое, но без включения заголовка <string>.

Итак,в основном, я должен написать строку как char [] и сделать указатели строк массивом указателей на несколько char[].

Проблема в том, что я понятия не имею, как это сделать правильно.

Обычно я пытался бы сделать что-то вроде этого:

int counter = 0
char * charptr[500]; //this is gonna store adresses to some char[] 's 
char OurString[500]; //variable that will hold user's input
while(true){
    cin >> OurString;
    charptr[counter] = new char [500];
    charptr[counter] = OurString // mistake - charptr[counter] gets assigned physical adress of OutString while that's not exactly what we want
}

Мне пришлось бы использовать какую-то функцию для копирования данных, начиная с некоторого диапазона адресов.Есть идеи, как это сделать?

Также обратите внимание, что это решение заставляет меня создавать массив символов фиксированного размера, в то время как при использовании строки не нужно определять размер строки - несоздание массива символов, способного содержать 500 символов - пустая трата памяти по сравнению со строкой?Если да, то как решается проблема в языке Си, где нет строкового класса?

Ответы [ 2 ]

0 голосов
/ 14 марта 2019

Мне бы пришлось использовать какую-то функцию для копирования данных, начиная с некоторого диапазона адресов. Есть идеи, как это сделать?

Стандартная библиотека C ++ имеет алгоритм копирования. Это называется std::copy. Если вы не можете использовать стандартную библиотеку, вы можете реализовать тот же алгоритм, используя цикл, оператор присваивания и арифметику указателя.

не создает ли массив символов, способных удерживать 500 символов, пустую трата памяти по сравнению со строкой?

Да.

Если да, то как решается проблема в языке Си, где нет строкового класса?

Подобно тому, как реализован сам std::string; В конце концов, std::string нельзя использовать для реализации std::string. Хотя базовая структура данных std::string может быть реализована в C так же, как и в C ++, способ получения и освобождения памяти несколько отличается, поскольку в C нет классов или исключений.

Строка - это просто особый случай последовательности объектов - это последовательность символов. Существует несколько структур данных с изменяемым размером, которые могут представлять последовательность. Например, std::string и std::vector реализованы с использованием структуры данных, называемой «динамический массив».

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

0 голосов
/ 13 марта 2019

Сделайте то, что вы просите, попробуйте что-то вроде этого:

#include <iostream>
#include <cstring>
using namespace std;

int main() {
    char text[500];
    char ** OldArray = nullptr;
    char ** NewArray = nullptr;
    unsigned int counter = 0;
    size_t textlen;

    cout << "Enter Strings: " << endl;
    while (cin.get(text, 500, ' ')) {
        if (strstr(text, "End")) break;

        NewArray = new char*[counter+1];
        for(int i = 0; i < counter; ++i) {
            NewArray[i] = OldArray[i];
        }

        textlen = strlen(text) /* or: cin.gcount() */ + 1;
        NewArray[counter] = new char[textlen];
        strncpy(NewArray[counter], text, textlen);

        delete [] OldArray;
        OldArray = NewArray;

        ++counter;
    }

    for (int i = 0; i < counter; ++i) {
        cout << OldArray[i] << " ";
    }

    for (int i = 0; i < counter; ++i) {
        delete[] OldArray[i];
    }
    delete[] OldArray;

    return 0;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...