Форум программистов, компьютерный форум CyberForum.ru
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 94, средняя оценка - 4.91
taras atavin
Ушёл с форума.
3569 / 1753 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
#1

std::string в char* - C++

11.06.2012, 14:13. Просмотров 13490. Ответов 40
Метки нет (Все метки)

Можно ли привести std::string к указателю на нуль-терминальную строку? Как?
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
11.06.2012, 14:13
Здравствуйте! Я подобрал для вас темы с ответами на вопрос std::string в char* (C++):

ошибка error: cannot convert 'std::string {aka std::basic_string<char>}' to 'std::string* {aka std::basic_stri - C++
на вод поступают 2 строки типа string. определить количество вхождений строки 2 в строку 1 ошибка error: cannot convert 'std::string {aka...

ошибка в программе (cannot convert 'std::string {aka std::basic_string<char>}' to 'const char*') - C++
int main() { string fileName, currWord, currMax = &quot;&quot;; cin&gt;&gt;fileName; freopen(fileName, &quot;r&quot;, stdin); while...

(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const& - C++
astxx::manager::connection::connection(std::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt; const&amp;, unsigned short); ...

Где и почему используют ту или иную строку std::string, char[], System::String^ ? - C++
Где и почему используют ту или иную строку std::string, char, System::String^ ? Объясните пожалуйста где нужно использовать...

char* vs std::string - C++
При чтении чужих сорцов, обратил внимание, что в роли аргументов для функций/методов, как правило используются указатели на массивы чаров,...

Std::string в const char* - C++
можно ли std::string превратить в const char* и как это сделать?

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
diagon
Higher
1929 / 1195 / 49
Регистрация: 02.05.2010
Сообщений: 2,925
Записей в блоге: 2
11.06.2012, 17:48 #16
Цитата Сообщение от Toshkarik Посмотреть сообщение
Да, сгенерированная строка не меняется при изменении самого объекта. Нужно вызывать повторно функцию, чтоб изменилась и Си строка. Мысль про освобождение памяти - скорей всего выделенная память под строку освобождается при удалении объекта.
Разве?
А мне казалось, что возвращается указатель на строку в объекте. Например. Но здесь надо стандарт читать.
0
Toshkarik
1141 / 858 / 51
Регистрация: 03.08.2011
Сообщений: 2,384
Завершенные тесты: 1
11.06.2012, 18:22 #17
Ну я вот так проверял. В любом случае и мой и Ваш варианты работают благодаря случаю. Как уже и сказали, строка действительна только до момента изменения самого объекта string.
0
Bers
Заблокирован
11.06.2012, 18:26 #18
Цитата Сообщение от diagon Посмотреть сообщение
А мне казалось, что возвращается указатель на строку в объекте.
Я это так понимаю:
Если внутри стринга данные лежат в непрерывном блоке, то было бы странным создавать новый блок, копировать туда данные, и выдавать наружу его указатель.
Ведь с таким же успехом можно сразу выдать указатель на итак уже имеющийся блок.

Однако, поскольку стандарт не запрещает реализовывать внутренее хранилище по разному. То - не факт, что это будет именно так.

Другими словами, в отдельных случаях (реализациях стринга) это может работать. А в каких то может и не сработать. В этом и заключается смысл слова:
Цитата Сообщение от grizlik78 Посмотреть сообщение
Этого, кстати, тоже никто не обещает.
Может быть будет работать. Может быть не будет. Если нужно гарантированно портабельное решение, то лучше на такое не опираться.

Добавлено через 3 минуты
Цитата Сообщение от Toshkarik Посмотреть сообщение
Ну я вот так проверял. В любом случае и мой и Ваш варианты работают благодаря случаю. Как уже и сказали, строка действительна только до момента изменения самого объекта string.
Есть предположение, что:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
#include <string>
 
int main()
{
   std::string str = "12345";
   
   const char *cstr1 = str.c_str(),
              *cstr2 = 0;
   
   std::cout << str << '\n' << cstr1 << std::endl;
   
   str = "qwerty";
   
   cstr2 = str.c_str();
   
   std::cout << '\n' << str << '\n' << cstr1  //cstr1  выводит в режиме только для чтения мертвую память.
                << '\n' << cstr2 << std::endl;
   
   return 0;
}
0
taras atavin
Ушёл с форума.
3569 / 1753 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
11.06.2012, 18:26  [ТС] #19
Не пойму, зачем вы обсуждаете подобные связи? Вопрос копия/оригинал имеет смысл только в контексте делита.
0
Bers
Заблокирован
11.06.2012, 18:29 #20
Pardon
0
Toshkarik
1141 / 858 / 51
Регистрация: 03.08.2011
Сообщений: 2,384
Завершенные тесты: 1
11.06.2012, 18:30 #21
Цитата Сообщение от Bers Посмотреть сообщение
Есть предположение, что:
Я тоже так думаю. Хотя возможно где то хранятся эти самые строковые литералы. Нужно попробовать проверить со строкой, вводимой пользователем.
0
grizlik78
Эксперт С++
1911 / 1443 / 112
Регистрация: 29.05.2011
Сообщений: 3,000
11.06.2012, 18:34 #22
Bers, что вкладывается в понятие мёртвая память и почему она мёртвая в том примере?
0
Deviaphan
Делаю внезапно и красиво
Эксперт C++
1287 / 1221 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
11.06.2012, 18:34 #23
Цитата Сообщение от Bers Посмотреть сообщение
то было бы странным создавать новый блок...
Если и правда терзают сомнения, то достаточно сделать ДВА вызова c_str и сравнить эти указатели. Если они разные, то возвращается копия (но это не так, разумеется). А если одинаковые, то на внутренний буфер.
И я не знаю, как работает codepad, но в MSVC в данной программе вообще std::sting str может быть удалён оптимизирующим компилятором, как ненужный объект. Этим можно было бы объяснить неожиданное поведение программы.
0
Bers
Заблокирован
11.06.2012, 19:16 #24
Цитата Сообщение от grizlik78 Посмотреть сообщение
Bers, что вкладывается в понятие мёртвая память и почему она мёртвая в том примере?
C++
1
2
3
4
5
char* str = new char[100500];
str[0] = '1';
str[1]= '\0'
delete [] str;
std::cout<<str<<std::endl;
Память сдохла. Но какое то время теоретически может хранить якобы актуальное значение

Добавлено через 2 минуты
Цитата Сообщение от Deviaphan Посмотреть сообщение
но это не так, разумеется
Ни разу не сталкивался с ситуациями, где это было бы так. Однако, в книжке по STL Джосаттис об этом предупреждает. Он говорит - стандарт не гарантирует, и полагаться на это нельзя.
0
grizlik78
Эксперт С++
1911 / 1443 / 112
Регистрация: 29.05.2011
Сообщений: 3,000
11.06.2012, 19:18 #25
Ясно. Но непонятно из-за чего такие подозрения в том коде. Вывод строки работает с константной ссылкой на строку и не может вызывать неконстантные функции. А раз так, то указатель остаётся валидным.
0
Bers
Заблокирован
11.06.2012, 19:24 #26
C++
1
2
3
4
5
6
7
8
9
10
11
12
int main()
{
       std::string str = "12345";
       const char *cstr1 = str.c_str(),   //смотрит на 12345
       cstr2 = 0;
       std::cout << str << '\n' << cstr1 << std::endl;
       str = "qwerty";        //внутреннее хранилище изменилось
       cstr2 = str.c_str();
       std::cout << '\n' << str << '\n' << cstr1 //по прежнему смотрит на 12345
                 << '\n' << cstr2 << std::endl;
       return 0;
}
Строка изменилась. И как бы ей и не нужны старые данные, но старый указатель об этом не знает.
0
grizlik78
Эксперт С++
1911 / 1443 / 112
Регистрация: 29.05.2011
Сообщений: 3,000
11.06.2012, 19:30 #27
Ах, да, присваивание я пропустил. Что ж, там что угодно может быть, согласен.
0
Bers
Заблокирован
11.06.2012, 19:54 #28
Цитата Сообщение от grizlik78 Посмотреть сообщение
Ах, да, присваивание я пропустил. Что ж, там что угодно может быть, согласен.
Просто в студии, когда внутренее хранилище меняется, то и старые указатели смотрят на это новое внутренее хранилище (иногда). А иногда уже не смотрят (когда реалок памяти стринга).

Как бы.. выдавая наружу си-строку, стринг нарушает инвариант своего класса. Это опасная процедура. И нужна лишь для совместимости с старым си-кодом. Лучше это избегать.

Я пользую сие только для сишных конструкций, и никогда при этом стринг не изменяю. Итак проблем хватает.
0
Deviaphan
Делаю внезапно и красиво
Эксперт C++
1287 / 1221 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
11.06.2012, 19:57 #29
Цитата Сообщение от Bers Посмотреть сообщение
Ни разу не сталкивался с ситуациями, где это было бы так.
В вышеприведённом коде в кодепаде всё выглядит так, будто возвращалась копия.
ТУт ещё такая фишка есть, что строки до 16 символов хранятся в объекте std::string в массиве фиксированного размера (в стеке) и только для бОльших строк выделяется память из кучи. С этим могло быть предыдущее поведение связанно.
0
Блудадей
59 / 6 / 1
Регистрация: 09.09.2011
Сообщений: 12
16.06.2012, 13:26 #30
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
#include <string>
 
int main()
{
   std::string str = "12345";
   
   const char *cstr1 = str.c_str(),
              *cstr2 = 0;
   
   std::cout << str << '\n' << cstr1 << std::endl;
   
   str = "qwert";//уменьшен до 5 символов
   
   cstr2 = str.c_str();
   
   std::cout << '\n' << str << '\n' << cstr1 << '\n' << cstr2 << std::endl;
   
   return 0;
}
данный код выводит(не происходит повторного выделения):
12345
12345

qwert
qwert
qwert
так что, скорее всего c_str возвращает ссылку на оригинал.
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
16.06.2012, 13:26
Привет! Вот еще темы с ответами:

std::string и/или char* - C++
Здравствуйте. пишу метод построчной обработки данных из файла Вот он: bool loadFromFile(std::string fileName) { ...

Перевод массива char в std::string в определенном формате - C++
Имеится char a=&quot;145&quot;; нужно его превратить в std::string , но чтоб string b=&quot;&quot;; тоесть чтоб скобки добавились. ...

Найти вхождение одного символа std::string в строку char* - C++
Каким образом можно найти вхождение одного символа std::string в строку char*? Наоборот то понятное дело как, но нужно именно так

Преобразовать const unsigned char* в std::string (или _bstr_t ) - C++
Здравствуйте старшие товарищи! Есть функция, которая возвращает результат типа const unsigned char*. а мне нужно получить ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
16.06.2012, 13:26
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru