2010-11-03 3 views
4

В recent question я узнал, что есть ситуации, когда вы должны просто передать char* вместо std::string. Мне очень нравится string, и для ситуаций, когда мне просто нужно передать неизменяемую строку, она отлично работает, чтобы использовать .c_str(). То, как я это вижу, неплохо использовать класс строк для удобства манипуляции. Однако для функций, которые требуют ввода, я в конечном итоге делает что-то вроде этого:Является ли std :: string лучшей идеей, чем char *, когда вам нужно передать ее как char *?

std::string str; 
char* cstr = new char[500]; // I figure dynamic allocation is a good idea just 
getstr(cstr);    // in case I want the user to input the limit or 
str = cstr;     // something. Not sure if it matters. 
delete[] cstr; 
printw(str.c_str()); 

Очевидно, что это не так, ну, просто. Теперь, я довольно новичок в C++, поэтому я не могу увидеть лес для деревьев. В такой ситуации, когда каждый вход должен быть преобразован в строку C и обратно, чтобы воспользоваться полезными методами string, это просто лучшая идея для человека и привыкания к строковым манипуляциям типа C ? Является ли такое постоянное обратное преобразование слишком глупым?

ответ

3

В примере, вы даете, вы можете вообще прочитать строку в std::string с помощью функции std::getline: http://www.cplusplus.com/reference/string/getline/

Конечно, это не делает все, что библиотека проклятий делает. Если вам нужен неконстантный char*, так что некоторые функции C могут его прочитать, вы можете использовать vector<char>. Вы можете создать vector<char> из string, и наоборот:

std::string  a("hello, world"); 
std::vector<char> b(a.begin(), a.end()); 

// if we want a string consisting of every byte in the vector 
std::string  c(b.begin(), b.end()); 

// if we want a string only up to a NUL terminator in the vector 
b.push_back(0); 
std::string  d(&b[0]); 

Так что ваш пример будет выглядеть так:

std::vector<char> cstr(500); 
getnstr(&cstr[0], 500); 
printw(&cstr[0]); 
+0

Мне сказали, чтобы не перепутать вход/выход из различных источников (в данном случае , iostreams и проклятия) - разве это не так? Кроме того, насколько мне известно, «вектор » не может расти по мере того, как функция считывает его, потому что эти функции ожидают массивы 'char' с фиксированной длиной; так есть ли реальное преимущество в использовании «вектора»? – Maulrus

+1

@Maulrus: Да, это правда. Если вы не можете обойтись с iostreams, и вам нужны проклятия, используйте вторую стратегию. Преимущество использования вектора заключается в том, что вам не нужно ничего освобождать, чтобы избежать утечек памяти. Для программиста на C, который может показаться не таким уж большим, но попробуйте написать некоторый код на C++, где некоторые из функций, которые вы вызываете, могут генерировать исключения, и вы скоро поймете, почему это плохая идея для хранения любого ресурса, который должен быть явно освобожден. В этом отношении, даже без исключений, неплохо не иметь код очистки в каждой функции, которую вы пишете. –

+0

Я вижу. Таким образом, использование 'vector ' такое же, как 'char *' в отношении функции, но с некоторой добавленной безопасностью C++? – Maulrus

1

Большинство реализаций std :: string :: c_str() (если не все) просто возвращают указатель на внутренний буфер. Нет накладных расходов.

Остерегайтесь, однако, что c_str() возвращает const char*, а не символ *. И что после вызова функции указатель станет недействительным. Таким образом, вы не можете использовать его, если функция делает что-то вроде записи обратно в переданную строку или создает копию указателя.