2009-02-02 9 views
-1

Итак ... , когда я иду:Почему c_str() печатает строку дважды?

cout<<stringName<<endl; 

я получаю:

NT 

Но когда я иду:

cout<<stringName.c_str()<<endl; 

я получаю:

NTNT 

Зачем?

+0

Вы используете wstring случайно. –

+0

Даже не знаю, что это. – Alex

+0

Вы делаете какую-либо вилку() в окрестностях - возможно, у вас есть несколько процессов, которые смывают более или менее одинаковые буферы. –

ответ

9

Быстрый тест с помощью следующего кода:

#include <string> 
#include <iostream> 

using namespace std; 

int main(void) { 
    string str = "NT"; 
    cout << str.c_str() << endl; 
    return 0; 
} 

производит один экземпляр NT, так это выглядит, как вы, вероятно, есть другой выход вызов где-то.

+0

Как это могло быть причиной? Предполагая, что он изменил эту строку только с «stringName» на «stringName.c_str()», что не может изменить количество строк, в которые печатается строка. Кроме того, он печатает новую строку, поэтому явно не два экземпляра этого кода. –

+0

@Larry Нет никаких указаний на то, как выглядит остальная часть кода или что один и тот же ввод использовался между прогонами, чтобы он мог быть где-то условным. Также нет гарантии, что предыдущий вызов будет включать в себя и endl. Я сказал «возможно» по какой-то причине. –

+0

@Kevin Если есть «другой выходной вызов», это происходит первым и не имеет новой строки. Я принимал во внимание, что единственное, что он изменил, это то, что одна строка, а не «другая». В любом случае, CHANGE в поведении, как описано, не учитывается только наличием другой команды печати «NT». –

1

Это не проблема с c_str(), но, вероятно, связано с какой-либо другой аномалией в остальной части программы.

Сделайте приложение «hello world», которое выполняет эти же операции, и вы увидите, что он отлично работает.

2

Показать еще код. Похоже, вы сделали cout << ealier и забыли, что вы это сделали. Что он печатает, если вы делаете cout<< "mofo" << stringName.c_str()<< "|||" << endl; Он говорит NTmofoNT|||? если это так, что вполне может быть, что случилось;)

4

Традиционный C строка (доступ через char const*) имеет последовательность символов, прерываемые символ 0. (не цифра 0, но фактическое нулевое значение, которое мы пишем, как '\0'.) Там нет явной длины — так различные строковые операции просто читают один символ за раз, пока он не достигнет '\0'.

A C++ std::string имеет явную длину в своей структуре.

Возможно ли, что расположение памяти символов вашей строки выглядит следующим образом:

'NTNT\0' 

но длина струны устанавливаются на 2?

Что приведет именно это поведение — манипулирования std::string непосредственно будет действовать, как это долго только два символа, но если вы делаете традиционные операции C использование s.c_str(), он будет выглядеть "NTNT".

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

Один из способов вы могли бы попасть в это состояние было бы на самом деле записи на персонажей струны, что-то вроде: strcat((char *)s.c_str(), "NT")

+0

Вы получите это поведение, только если std :: string :: c_str() неисправен. c_str() гарантируется стандартом (21.3.6 [1]) для указания массива (не обязательно того же хранилища, что и строка, используемая внутри), заканчивающегося символом \ 0 –

+0

@Steve, а не если c_str() не делает ничего, и данные уже поддерживаются с нулевым завершением. Затем, если вы перепишете этот нулевой ограничитель, напрямую манипулируя им данными(), он может получить этот результат. –

+0

И вообще, если вы сделали что-то недействительное для строкового объекта, и результат состоит в том, что c_str() не делает то, что вы ожидаете, это не значит, что c_str() неисправен ;-) –