Преобразование строки, на которую ссылается указатель - PullRequest
1 голос
/ 26 мая 2020

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

#include <iostream>
#include <vector>
#include <string>
#include <iterator>
#include <algorithm>
#include <cctype>

int main()
{
    std::vector<std::string> vec = {"AbBBBcCc", "AFFDDsDCc"};

    for (std::vector<std::string>::iterator it = vec.begin(); it != vec.end(); ++it)
    {
        std::transform(*it->begin(), *it->end(), *it->begin(),
                       [](char c) { return std::tolower(c); });
        std::cout << *it << std::endl;
    }
    return 0;
}

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

error: invalid type argument of unary '*' (have 'char')
 4298 |  *__result = __unary_op(*__first);

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

Спасибо.

Ответы [ 2 ]

3 голосов
/ 26 мая 2020
std::transform(*it->begin(), *it->end(), *it->begin(),

it здесь выполняет итерацию по std::string s в векторе и ссылается на некоторую строку в векторе. Его перегрузка -> преобразуется в строку, на которую в настоящее время ссылается итератор. Следовательно:

it->begin()

вызывает std::string::begin(), который возвращает итератор в начало строки, к ее первому символу. Следовательно,

*it->begin()

Дает вам первый символ в строке, а *it->end(), конечно, неопределенное поведение. Разграничение конечного значения итератора всегда является неопределенным поведением, поэтому выражение «*it->end()» само по себе должно заставить вас задуматься и дать вам пищу для размышлений. Вы явно хотели сделать:

  std::transform(it->begin(), it->end(), it->begin(),
                   [](char c) { return std::tolower(c); });
0 голосов
/ 26 мая 2020

Работает следующий код -

   #include <iostream>
#include <vector>
#include <string>
#include <iterator>
#include <algorithm>
#include <cctype>

char* lower(char c){

}
int main()
{
    std::vector<std::string> vec = {"AbBBBcCc", "AFFDDsDCc"};

    for (std::vector<std::string>::iterator it = vec.begin(); it != vec.end(); ++it)
    { std::string data=*it;
        std::transform(data.begin(), data.end(), data.begin(),
    [](unsigned char c){ return std::tolower(c); });
        std::cout << data<< std::endl;
    }
    return 0;
}

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

std::transform(it->begin(), it->end(), it->begin(), [](char c){ return std::tolower(c); });

Есть и другой способ если вы хотите удержать указатель, используя *, а затем преобразовать его в нижний регистр -

std::transform((*it).begin(), (*it).end(), (*it).begin(),
                       [](char c) { return std::tolower(c); });

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

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