c ++ элемент массива строк (символы) опирается на исходную строку - PullRequest
2 голосов
/ 23 декабря 2011

Небольшой контекст: я пытаюсь создать очень простую хэш-функцию / хеш-таблицу, как , описанную здесь . Я в основном на первом шаге, слепо добавляя ключ к массиву на основе буквы, с которой он начинается (пока не проверяется, занято ли место). Код, который я использую для этого:

int main(int argc, char **argv) {
    char *arrayKeys[300];
    std::string aName("Charles");

    char *aNameCpy = new char[aName.size() + 1];
    std::copy(aName.begin(), aName.end(), aNameCpy);
    aNameCpy[aName.size()] = '\0';

    int kPos = storeKey(arrayKeys, aNameCpy);

    std::cout << "The new position in arrayKeys for 'Charles' is:  " <<
        kPos << "\ncontaining the text: " << arrayKeys[kPos] << std::endl;
    delete[] aNameCpy;  
    return 0;
}

int storeKey(char **keys, char *key) {

    int charLett = -1;
    charLett = (int)key[0];
    if(charLett != -1)
        charLett = charLett - 65;

    keys[charLett * 10] = key;

    return charLett*10;
}

Мой вопрос: как я могу добавить строку в массив (arrayKeys), если она полностью отделена от массива и не зависит от исходной строки? Если я удаляю копию строки (aNamCpy) перед тем, как распечатать ключ массива, ключ массива превращается в искаженные символы. Я копирую строку перед отправкой в ​​функцию, потому что мне нужна неконстантная строка для добавления в массив arrayKeys (чтобы ее можно было изменить), и любой метод строки, на который я смотрел, возвращал const.

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

Ответы [ 2 ]

2 голосов
/ 24 декабря 2011

Вот как я могу изменить код, чтобы использовать более современные конструкции C ++.Я думаю, вы найдете этот способ проще в использовании.

int storeKey(vector<string> &keys, const string &key) {
    int charLett = -1;

    if (!key.empty()) {  // you weren't doing this before!
        charLett = key[0];
        charLett = toupper(charLett) - 'A';
        keys[charLett * 10] = key;
    }

    return charLett*10;
}

int main() {
    vector<string> arrayKeys(300);
    std::string aName("Charles");

    // No need to bother with the awkward copying.
    // std::vector and std::string will take care of it for us.

    int kPos = storeKey(arrayKeys, aName);

    if (kPos >= 0) {
        cout << "The new position in arrayKeys for 'Charles' is:  " <<
            kPos << "\ncontaining the text: " << arrayKeys[kPos] << endl;
    }

    // Don't have to remember to delete anything because nothing was new'ed.
    return 0;
}
1 голос
/ 24 декабря 2011

(у @ Kristo правильная идея. Я просто добавлю комментарий к вопросу в ответ на вопрос.)

По сути, не удаляйте aNameCpy. Вы требуете, чтобы копия напоминала действительную, и поэтому ее не следует удалять. Вы должны удалять строки только в том случае, если и когда-либо удаляете весь хеш.

C ++ все еще очень новый для меня, поэтому я не могу понять, как манипулировать неконстантная часть

Вы можете объявить keys и key const char **keys, const char *key. keys указатель на указатель на символ. Точнее, это указатель на неконстантный указатель на const char . Другими словами, вы можете изменить keys, вы просто не можете изменить действительные символы, на которые он указывает (косвенно).

Итак, просто укажите const в вашем объявлении storeKey int storeKey(const char **keys, const char *key) и обновите arrayKeys соответственно const char *arrayKeys[300];

Еще одна проблема стиля: вам нужно скопировать строку внутри storeKey, а не в main. Это лучший дизайн, так как читателю ясно, что storeKey «владеет» копией.

int storeKey(char **keys, const char *key) {
    char * the_copy = new char[strlen(key)+1];
    strcpy(the_copy, key);

... и т. Д.

Но, короче, используйте C ++ string вместо всего этого, если можете!

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