Строка c ++, сформированная путем копирования индексных символов из другой уже инициализированной строки. Невозможно напечатать недавно сформированную строку, используя cout

В C ++ я создал новую строку (класс строки), скопировав символы с указанием индекса из другой строки (класс строки), которая уже была инициализирована.

Но я не могу распечатать эту новую строку на экране, используя cout, С помощью c_str() Я могу распечатать его, используя cout, Но не c_str() нужен только при использовании printf() потому что ему нужна строка типа c?

#include <cstring>
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;

int main() {
int i;
string a,b;
cin>>a;
for(i=0;a[i]!='\0';i++){
b[i]=a[i];
}
cout<<b;
return 0;
}

РЕДАКТИРОВАТЬ: Спасибо за помощь! Но, возможно, я не совсем понял свой вопрос, поэтому это основные проблемы, которые у меня есть. Пожалуйста, прочитайте следующее, и если бы вы могли помочь мне дальше, это было бы здорово! (Также я понимаю b=a; это самый простой способ назначить, но я пытаюсь понять строки и, следовательно, вопрос.)

а) я не знаю, когда строка cpp заканчивается нулем, а когда нет, но в этом случае строка после инициализации была нулевой, потому что цикл завершился и закончился после последнего символа строки a, потому что при выходе из цикл и делать cout<<a[i]; последний символ печатается.

б) в цикле, после назначения, когда я включаю cout<<b[i]; он распечатывает ожидаемое нами значение, которое было присвоено b [i]. Так что b [i] существует по какой-то странной причине.

c) Вне цикла for, в конце программы, когда я cout<<b[2]; он печатает третий символ строки. И если я сделаю cout<<b.c_str(); распечатывает всю строку. Это только если я cout<< b; что ничего не печатается. Почему это?

0

Решение

Вы могли заметить, что std::string не ведет себя как обычная строка в стиле C Важно это заметить.

Во-первых, такое прямое назначение не работает. Настоящая причина в том, что это не меняет размер строки. Вы можете сами это выяснить, выведя b.size()или проверяя, что оба b.start() а также b.end() ссылаются на тот же символ, b[0],

Ваш эксперимент будет работать, если вы сначала изменили размер b к тому же размеру, что и a,

b.resize(a.size());

Во-вторых, взгляните в свою петлю. Не сравнивать с \0 как будто это была строка в стиле C. Вместо этого проверьте, i < a.size()нет гарантии std::string будет нулевым (\0) прекращено

Что вы действительно должны сделать, тем не менее, это просто назначить a для b, и b будет иметь копию a, как вы и предполагали.

b = a;
3

Другие решения

Вам нужно выделить место в b прежде чем начать переписывать его символы с помощью b[n], Так b.resize(...) будет необходимо. В противном случае вам нужно добавить каждый символ в конец, используя b += a[i];,

Также std::string не прекращено поэтому, пожалуйста, не проверяйте \0, использовать их size():

Учти это:

int main()
{
int i;

string a, b; // these are both empty

std::cout << "a.size() = " << a.size() << '\n';
std::cout << "b.size() = " << b.size() << '\n';

cin >> a; // now a contains something

std::cout << "a.size() = " << a.size() << '\n';
std::cout << "b.size() = " << b.size() << '\n';

// for(i = 0; a[i] != '\0'; i++) // no don't test for null
// {
//  b[i] = a[i]; // no b has no spaces
// }

for(std::size_t i = 0; i < a.size(); ++i)
b += a[i]; // increases b's size by one each time

std::cout << "b.size() = " << b.size() << '\n';

cout << b;
}

Чтобы ответить на дополнительные вопросы:

а) Это внутренняя деталь реализации, которая std::string теряет силу Дело в том, что нулевой завершающий символ находится за пределами законных границ общедоступный интерфейс и это технически «неопределенное поведение» для доступа к нему. правильный способ найти конец std::string использует его size() функция или ее end() итератор.

б) Это просто удача, если за концом строки выделена память. Даже если там есть память, она не является частью строки и будет не быть скопирован во время правовой строковая операция как a = b;,

с) Это полностью не определено поведение. Скорее всего std::cout << b; смотрит на size() строки, которая zero и решает ничего не печатать, потому что size() является zero (см. мой пример). тем не мение c_str() просто возвращает адрес памяти начала строки. Из одного адреса памяти std::cout не может сказать, насколько велика предполагаемая строка. Поэтому он просто печатает символы, пока не найдет ноль. Это чистая удача, если она напечатает то, на что вы надеетесь.

2

b пустой. Назначение b[i] имеет неопределенное поведение для любого значения i,

a[i]!='\0' условие допустимо только в том случае, если ваш компилятор поддерживает C ++ 11 или более позднюю версию. До C ++ 11 str[str.size()] имеет неопределенное поведение.


Вы можете решить первую проблему, сначала изменив размер b, Если у вас есть поддержка C ++ 11, цикл, основанный на диапазоне, будет намного проще. Если у вас нет C ++ 11, тогда допустимым является следующее:

b.resize(a.size());
for(i=0; i < a.size(); i++)

Хотя писать цикл для копирования строки немного глупо. Вы можете просто использовать назначение:

b = a;

а) я не знаю, когда строка cpp заканчивается нулем, а когда нет, но в этом случае строка после инициализации была нулевой, потому что цикл завершился и закончился после последнего символа строки a, потому что при выходе из цикл и делать cout<<a[i]; последний символ печатается.

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

б) в цикле, после назначения, когда я включаю cout<<b[i]; он распечатывает значение, которое мы ожидаем, было просто присвоено b[i], Так b[i] существует по какой-то странной причине

Это не значит что b[1] «существует». Поведение не определено.

c) Вне цикла for, в конце программы, когда я cout<<b[2]; он печатает третий символ строки. И если я сделаю cout<<b.c_str(); распечатывает всю строку. Это только если я cout<< b; что ничего не печатается. Почему это?

Это потому, что поведение не определено.

1
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector