C++ хранит элемент массива строк в переменной

В настоящее время я кодирую на C++ и довольно новичок в этом. У меня возникают проблемы с преобразованием элемента массива строк в переменную. Оператор cout dcity [selection-1] работает должным образом. Однако я не могу сохранить dcity [selection-1] в переменной с именем leaveLocation. Visual Studios выдает ошибку, что нет подходящей функции преобразования из строки в char. Есть ли у кого-нибудь совет, как это правильно хранить? Спасибо!

int main()
{

int selection = 0;
char departureLocation;


std::string dcity[] = { "Seattle Detroit Seattle Chicago Houston Seattle" };
std::cout << "Please choose a number from the list";
std::cin >> selection;
std::cout << dcity[selection-1];


departureLocation=dcity[selection-1]

};

Вам нужен вектор строк.

user2100815 26.09.2018 22:18

@NeilButterworth В показанном коде нет доказательств того, что std::vector лучше подходит для предполагаемой цели, чем массив.

Swordfish 26.09.2018 22:21

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

john 26.09.2018 22:48

@Swordfish Векторы почти всегда предпочтительнее массивов, потому что они несут с собой свой размер и, таким образом, могут легко передаваться как параметры функции.

user2100815 26.09.2018 22:59

@NeilButterworth Поскольку массив городов, из которых можно уехать, вряд ли изменится во время выполнения, я бы предпочел std::array<std::string> или `` std :: array <char const *> `.

Swordfish 26.09.2018 23:03

@Swordfish Напротив, многие, многие вещи (фактически, большинство вещей) меняются во время выполнения. В случае приложения авиакомпании, аэропорты могут закрываться или открываться, или в них могут действовать временные специальные предложения и т. д. В любом случае, это не меняет того факта, что если вы передаете вектор функции, функция знает размер вектор, но это не так для массивов, что было моей точкой зрения. Когда вы говорите такие вещи, мне интересно, писали ли вы когда-нибудь большое приложение на C++.

user2100815 26.09.2018 23:06

@NeilButterworth Я написал свой комментарий, имея в виду, что программа boodaloo1s, скорее всего, предназначена для начинающих, изучающих C++, и не будет использоваться в сценарии, когда «аэропорты могут закрываться или открываться, или на них могут действовать временные специальные предложения и т. д.». «если вы передадите вектор функции, функция знает размер вектора, но это не так для массивов, на что я обращал внимание». std::array знает свой размер.

Swordfish 26.09.2018 23:16

@Swordfish std :: массивы не несут с собой свой размер - они имеют только один размер - точно так же, как массивы в стиле C. Понятия не имею, почему вы так возражаете против идеи использования векторов, которые чище, проще, проще, лучше и т. д.

user2100815 26.09.2018 23:24
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
8
4 023
5

Ответы 5

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

char departureLocation;

Это означает, что отправлениеLocation - это переменная типа char или одиночный символ. Таким образом, «C» может перейти в исходное местоположение, а «Чикаго» - нет, поскольку это более одного символа.

Вы также объявили свой массив так:

std::string dcity[] =

Здесь вы определили тип массива как std :: string. Таким образом, элементы массива - это строки, а не символы.

Короткий ответ заключается в том, что вам нужно изменить тип отправленияLocation на строку, когда вы ее объявляете, а не на char. Что-то вроде:

std::string departureLocation;

Я также не видел никаких операторов включения в приведенном выше коде. Чтобы C++ распознал строковый класс, вам нужно убедиться, что следующее находится где-то в верхней части вашего кода:

#include <string>

В дополнение к проблемам, упомянутым выше, довольно ясно, что когда вы писали этот std::string dcity[] = { "Seattle Detroit Seattle Chicago Houston Seattle" };, вы действительно должны были написать этот std::string dcity[] = { "Seattle", "Detroit", "Seattle", "Chicago", "Houston", "Seattle" };. Строки не разделяются автоматически на пробелы, вам нужно написать несколько строк, разделенных запятыми.

john 26.09.2018 22:44

dcity - это массив std::string. departureLocation - это char, который может содержать только один символ. Чтобы сохранить (скопировать) элемент массива dcity, departureLocation должен иметь тип std::string (или любой другой тип, который может быть построен на основе std::string):

std::string dcity[] = { "Seattle Detroit Seattle Chicago Houston Seattle" };
std::string departureLocation = dcity[0];

Имейте в виду, что dcity - это массив, состоящий только из одного элемента. Возможно, вам нужен массив, в котором каждый город представляет собой отдельный элемент массива:

std::string dcity[] = { "Seattle", "Detroit", "Seattle",
                        "Chicago", "Houston", "Seattle" };
std::string departureLocation = dcity[2];
std::cin >> selection;
std::cout << dcity[selection-1];

Также вы должны выполнить некоторую проверку ошибок, прежде чем использовать вводимые пользователем данные в качестве индекса массива:

if (!(std::cin >> selection) || selection < 1 || selection > sizeof(dcity) / sizeof(*dcity)) {
    std::cerr << "Input error!\n";
    return EXIT_FAILURE;
}
std::string departureLocation = dcity[selection - 1];

Если вам не нужны независимые копии элементов массива, вы также можете использовать ссылку на std::string:

std::string &departureLocation = dcity[selection - 1];

Имейте в виду, что изменения в строке, использующей departureLocation, теперь будут отражаться на ссылках на элемент массива departureLocation. Если вы не хотите разрешать изменения, используйте ссылку const:

std::string const &departureLocation = dcity[selection - 1];

Это массив строки один.

user2100815 26.09.2018 22:27

Вы можете сохранить выбор в std :: string, потому что char может хранить только один символ. Также будьте осторожны с тем, где вы обращаетесь к своему массиву, чтобы не выйти за пределы (что произойдет, если кто-то введет 1000 и т. д.), И что пользователи, не являющиеся программистами, индексируют списки, начинающиеся с 1. Вы можете попробовать этот код:

#include <iostream>
#include <string>

int main()
{
    const auto Cities = { "Seattle", "Detroit", "Seattle", "Chicago", "Houston", "Seattle" };
    std::cout << "Please choose a number from the list (1-" << Cities.size() << "): ";

    int selection = 0;
    std::cin >> selection;
    if (selection < 1 || selection > Cities.size()) {
        std::cout << "\ninvalid selection!\n";
        return -1;
    }

    const std::string departureLocation = *(Cities.begin() + selection - 1);
    std::cout << "\nyou selected: " << departureLocation;

    return 0;
};

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

user4581301 26.09.2018 22:46

Во-первых, компилятор думает, что в массиве только один элемент, потому что массивы в C++ должны иметь запятые между каждым элементом, а каждая строка должна быть заключена в двойные кавычки. Вторая ошибка заключается в том, что вы пытаетесь сохранить данные типа string в переменная с типом данных char.

Код

#include<string>
#include<iostream>

using namespace std;
int main()
{

int selection=0;
string depaturelocation;
string dcity[] = {"Seattle","Detroit","Seattle","Chicago","Houstan","Seattle"};
int size=sizeof(dcity)/sizeof(dcity[0]);
for(int i=0;i<size;i++)
{
   cout<<i+1<<" : "<<dcity[i]<<endl;
}
cout<<"please enter the destination no:";
cin>>selection;

for(int i=0;i<size;i++)
{
    if (selection-1==i)
    {
        depaturelocation=dcity[i];
    }
}
cout<<"destination:"<<depaturelocation;
return 0;
}

Вам действительно не нужно писать цикл для выполнения назначения depaturelocation

john 26.09.2018 22:46

Да, это не обязательно, вы можете напрямую присвоить значение Depaturelocation

user9110300 26.09.2018 23:00

Ваш код требует небольших изменений. 1. Массив инициализируется указанием значений его компонентов, разделенных запятой. Обратите внимание, что каждый отдельный элемент должен быть того же типа, что и объявленный массив. 2. C++ очень строг к сопоставлению типов. Мы можем назначать объекты только одного типа. В приведенном выше коде строковый объект назначается символьной переменной, что противоречит правилу. Строка C - это массив символов, оканчивающийся нулевым символом (\ 0). В C++ строка более продвинута, и это объект, который имеет очень полезную функцию-член. Например, чтобы получить длину строки, просто скажите obj.length (). Нам нужен массив символов, поскольку в строке может быть более одного элемента char. Нам нужно иметь c-строку строкового объекта, чтобы попасть в массив символов. См. Измененный код ниже.

#include <iostream>
#include <cstring>
#include <string>
using namespace std;    //std::  is not required in front of cout 
int main()
{
    int selection = 0;

    string dcity[] = { "Seattle", "Detroit" ,"Seattle", "Chicago", "Houston","Seattle" };
    cout << "Please choose a number from the list";
    cin >> selection;
    cout << dcity[selection-1] << endl;

    char departureLocation[dcity[selection-1].length()+1];
    strcpy(departureLocation,dcity[selection-1].c_str());
    cout << departureLocation;
   // cout << *c;
    return 0;
}

Не используйте строки C, если от них нет никакой пользы. Также в C++ нет такой вещи, как массивы переменной длины.

Swordfish 26.09.2018 23:00

Спасибо за ваш комментарий. Но можете ли вы объяснить, почему не следует использовать строки C, если это не приносит большой пользы. А про массивы переменной длины в своем посте я ничего не сказал.

Kaushal 26.09.2018 23:05

«И я ничего не сказал о массивах переменной длины в своем посте». Вы их использовали: "char departureLocation[dcity[selection-1].length()+1];"

Swordfish 26.09.2018 23:07

Массивы переменной длины допускаются расширением в некоторых компиляторах, но результаты могут быть неудачными. Например, они нарушают поведение sizeof во время компиляции. Предпочитаю использовать vector.

user4581301 27.09.2018 01:04

Другие вопросы по теме