Как напечатать количество элементов списка

У меня есть код ниже:

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

class YTchannel{
public: 
    string name;
    string owner;
    int subs;
    list<string> video_title;
};

int main(){

    YTchannel ytc; 
    ytc.video_title = {"A", "B", "C"};
    for(string videotitle: ytc.video_title){
        for(int i=1;i<=videotitle.size();i++){
            cout<<i<<videotitle<<endl;
            break;
        }
    }

Я хочу отобразить список заголовков видео с их соответствующим номером: 1А 2Б 3С

Но если я запущу код, я получу: 1А 1Б 1С

Зачем вы написали вложенный цикл? И почему вы используете list<string> вместо vector<string>?

UnholySheep 06.02.2023 10:17

Что ж, довольно очевидно: внутренний цикл перебирает длину заголовков... Попробуйте вставить заголовок длиннее одного символа, например "ABC", и вы заметите: 1ABC 2ABC 3ABC (наряду с, возможно, другим выводом, если вы оставите их в списке .

Aconcagua 06.02.2023 10:20

Почему это помечено как упс? Я действительно не вижу никакой связи с ООП.

Konrad Rudolph 06.02.2023 10:21

Обратите внимание, что если у вас нет особых требований к использованию списка, контейнером по умолчанию в C++ почти всегда должен быть std::vector.

Some programmer dude 06.02.2023 10:22

То, что вы должны прочитать о использовании пространства имен std — до того, как эта плохая практика превратится в плохую привычку ;)

Aconcagua 06.02.2023 10:58

Кроме того, наличие безусловного break внутри цикла for гарантирует, что он работает только один раунд. Как если бы не было петли...

BoP 06.02.2023 11:02

Использование ключевого слова auto делает ваш код более удобным для сопровождения, учтите, что вам нужно заменить std::string на какой-то другой тип; тогда вам не нужно будет настраивать петлю: for(auto videotitle : tyc.video_title)

Aconcagua 06.02.2023 11:09
Стоит ли изучать 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
7
108
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Вы печатаете длину строки ("A", "B" или "C"), а не списка. Вы хотите:

    ytc.video_title = {"A", "B", "C"};
    auto it = ytc.begin()
    for(size_t i =0; i < ytc.size(); ++i){
        cout<<i<<*it++<<endl;
    }

Однако то, что вы, вероятно, действительно хотите, это:

#include <iostream>
#include <vector>
#include <algorithm>

// Include the headers for std::string
#include <string>

// Don't use 'using namespace std'

// Structs are all public by default, so they're a better choice than a class here
struct YTchannel{
    std::string name;
    std::string owner;
    int subs;
    // Vector is a better choice than list unless you know why it isn't
    std::vector<string> video_title;
};

int main(){
    YTchannel ytc; 
    ytc.video_title = {"A", "B", "C"};

    for(auto it = ytc.begin(); it != ytc.end(); ++it){
        std::cout << std::distance(ytc.begin(), it) << videotitle << std::endl;
}

Лично я бы предпочел: for(auto it = begin(); it != end(); ++it) { std::cout << it - begin() << ...; } избегать дополнительной переменной, видимой вне цикла. Хотя очевидно, что цикл итератора используется реже, он в любом случае более идиоматичен (или почему цикл for, основанный на диапазоне, определяется int в терминах иначе?). Конечно, требуется переключиться на std::vector, но в любом случае это рекомендуется.

Aconcagua 06.02.2023 10:24

@Aconcagua Я согласен - и я не уверен, что согласен, что он все равно используется меньше. Но в этом случае самая тривиальная реализация, вероятно, та, которая перебирает индексы, а не итераторы. Мое предпочтительное решение, конечно, просто использовать итераторы, std::vector и std::distance вместо того, чтобы вообще иметь счетчик :)

DividedByZero 06.02.2023 10:36

Что ж, цикл for на основе счетчика и диапазона (особенно в варианте С++ 20, см. другие ответы) по-прежнему является привлекательной альтернативой — и если есть причины сохранить список (например, для требования указателей на, которые могут стать недействительными с std::vector) тогда я бы определенно пошел по этому пути ;) — с сохранением списка std::distance потребовалась бы внутренняя итерация — невидимое превращение печати в алгоритм O(n²) :(

Aconcagua 06.02.2023 10:39

Да, кстати: for(auto& s : vector) { auto distance = &s - &vector.front(); } было бы еще альтернативой разрешить диапазон, основанный на цикле for без дополнительной переменной, хотя содержащаяся арифметика указателя может перегрузить автора вопроса;)

Aconcagua 06.02.2023 10:43

@Aconcagua, если список требуется, я согласен. Но то, что мы, вероятно, имеем здесь, это Java-программист, который выбрал неправильный контейнер :) (также, если вам нужны гарантии валидности итератора, используйте двухстороннюю очередь)

DividedByZero 06.02.2023 10:43
std::deque имеет более слабые гарантии, если стереть посередине! См. en.cppreference.com/w/cpp/container/deque#Iterator_invalidat‌​ion
Aconcagua 06.02.2023 10:48

Первая петля:

for(string videotitle: ytc.video_title)

перебирает все строки в списке.

Второй цикл:

for(int i=1;i<=videotitle.size();i++)

перебирает все символы в текущей строке. И в этом цикле вы печатаете всю строку на каждой итерации.

Простое решение состоит в том, чтобы сохранить отдельный счетчик, который вы увеличиваете в одном первом цикле:

unsigned counter = 1;
for (auto const& title : yts.video_titles)
{
    std::cout << counter++ << ' ' << title << '\n';
}

Мне нравится вариант С++ 20 из другого ответа - хотя и не (пока?) Правильный - за то, что не требуется переменная, видимая вне тела цикла; рекомендовал бы size_t как правильный тип (соответствующий size() возвращаемому значению контейнеров) — несмотря на то, что unsigned несоответствие должно быть нереалистичным;)

Aconcagua 06.02.2023 10:35
Ответ принят как подходящий

У вас есть «перерыв» в вашем цикле, поэтому вы никогда не увеличиваете счетчик.

Кроме того, в C++20 вы можете сузить область действия, используя оператор init в цикле на основе диапазона.

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

class YTchannel{
public: 
    string name;
    string owner;
    int subs;
    list<string> video_title;
};

int main(){

    YTchannel ytc; 
    ytc.video_title = {"A", "B", "C"};
    int counter = 0; 
    for(string videotitle : ytc.video_title){
        cout<<++counter<<videotitle<<endl;
    }

    // C++20
   //YTchannel ytc; 
   //ytc.video_title = {"A", "B", "C"};
   //for(int counter = 0; string videotitle : ytc.video_title){
   //   cout<<++counter<<videotitle<<endl;
   //}
}

Да, я обновил ответ до того, как вы сделали свой комментарий. Что касается ссылок и прочего - это просто вопрос использования. Может быть, кто-то захочет сделать копию вместо того, чтобы брать ссылку. ОП, очевидно, новичок, и вы, вероятно, сбиваете его с толку, вводя ссылки, которые он, вероятно, не знает. НЕ усложняйте.

bielu000 06.02.2023 10:32

@ bielu000 bielu000 не уверен, что я согласен с тем, что настаивать на хорошем стиле кодирования с самого начала слишком сложно.

DividedByZero 06.02.2023 10:38

Хороший стиль кодирования — это не то, что должно интересовать новичка. Точка. Я работал со студентами, и они обычно боятся C++ именно тем, что навязывают им слишком много вещей одновременно, они не понимают. Придет время, когда новичок узнает, что такое ссылка, как ее использовать и как она влияет на производительность.

bielu000 06.02.2023 10:41

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

Aconcagua 06.02.2023 10:56

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