2013-04-16 4 views
0

Я читал многочисленные сообщения о том, почему два строковых литерала не могут быть добавлены в C++ и т. Д., А оператор + поддерживает добавление строкового литерала к целому.Объединение двух строк

Однако, я пытаюсь понять ошибку компилятора в следующем коде:

string str1, str2, str3; 
int i = 10; 

str1 = "Hello " + i; 
str2 = i + "Mars"; 
str3 = "Hello " + i + "Mars"; 

инициализации str1 и str2 работают отлично, но строительство str3 дает следующее сообщение об ошибке:

example.cpp: In function int main() :
example.cpp:20:27: error: invalid operands of types const char* and const char [5] to binary operator+

Q1: В сообщении об ошибке, я понимаю, const char [5] относится к "Mars". Что означает const char*, целое число i после преобразования в char *?

Q2: operator+ оставил к правой ассоциативности, я предполагаю, что строительство str3 можно записать в виде:

str3 = ("Hello " + i) + "Mars"; 

Проводит ли ("Hello " + i) к char *?

3: В следующем коде:

str5 = string("foo ") + "bar "; 
str6 = string("foo ") + "bar " + i; 

Установка str5 компилируется нормально, но str6 генерирует нагрузки (страницы и половину) сообщений об ошибках. Каков результат string("foo ") + "bar ", это "string"?

Заранее благодарим за понимание.

+2

Вы пытаетесь добавить строку и целое число. Это ошибка. Рассмотрите: http://stackoverflow.com/questions/5590381/easiest-way-to-convert-int-to-string-in-c – squiguy

ответ

7

str1 принимает строковый литерал (действительно массив постоянных символов), затухает его указатель на первый символ, и добавляет десять к этому указателю, в результате const char *, что это за пределами вашего строкового литерала, что неопределенное поведение , так как это уже не один конец.

str2 делает то же, что и str1, но идет еще дальше за пределы.

str3 делает то же самое с "Hello" и i, а затем пытается добавить полученную const char * свою вторую строку буквального (опять же, массив постоянных символов, который распадались из-за передается в функцию). Нет перегрузки operator+, который займет const char * и const char *, таким образом вы получите ошибки.

Обратите внимание, что ни одна из них не будет работать так, как вы хотите. То, что компилируется, - это неопределенное поведение. std::string перегружен operator+ в соответствии с его целями, поэтому добавление строкового литерала к std::string просто объединяет его. Чтобы добавить целое число немного неоднозначно, хотя (и, следовательно, не поддерживается operator+), так что вы должны сделать ваши намерения ясно путем преобразования его в строку первой:

str6 = string("foo ") + "bar " + std::to_string(i); 
1

Дело в том, что «Hello» литерал рассматривается как char *. Вы можете сделать арифметику указателя на char *, добавив int к ней - вы говорите «10 символов за пределами того, что указывает символ». Другими словами, мусор.

Одним словом, вам нужно использовать boost :: lexical_cast или istringstream для такого рода вещей.

+0

О, я только что заметил, когда печатал «Привет» + 10, это не «Привет» + «10», но, как вы указали, значение - это мусор. Спасибо. –

+1

@AhmedA try 'std :: cout << (« Hello »+ 1) << std :: endl;', чтобы получить более четкое представление о том, что происходит. –

3

Q1: In the error message, I understand const char [5]' refers to "Mars". What doesconst char*' refer to, the integer i after conversion to a "char *"?

Это относится к результату "Hello" + i.

Q2: operator+ has left-to-right associativity, I am guessing the construction of str3 can be written as: str3 = ("Hello " + i) + "Mars";

Does ("Hello " + i) evaluate to a char *?

Да. Однако он оценивает const char*.

Q3: What is the outcome of string("foo ") + "bar ", is it a "string"?

Да, это std:string. Вы получаете ошибку в str6 = string("foo ") + "bar " + i;, потому что вы не можете добавить строку и целое число.

Примечание стороны - ни один из трех следующих утверждений iniatialization:

str1 = "Hello " + i; 
str2 = i + "Mars"; 
str3 = "Hello " + i + "Mars"; 

Они все оператор присваивания вызова.

+0

Однако для добавления строкового литерала к целому числу (как видно из установки str1 в моем основном сообщении). Мне любопытно, почему это не было реализовано, добавив строку в целое число. –

+2

@AhmedA, для 'std :: string', вы хотите увеличить его длину на это число? Объединить число? Добавить символ с этим числовым значением? Это действительно лучше, как отдельная операция. Что касается литерала, он принимает необходимую арифметику указателя. – chris

+0

@AhmedA Это действительно, но только если вы не добавляете больше, чем длина литерала (см. Сообщение Криса). Он не делает конкатенации, однако, он увеличивает указатель на литерал. – jrok

Смежные вопросы