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

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

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

std::string в char* - C++

11.06.2012, 14:13. Просмотров 13872. Ответов 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* и как это сделать?

40
Toshkarik
1141 / 858 / 51
Регистрация: 03.08.2011
Сообщений: 2,386
Завершенные тесты: 1
16.06.2012, 13:41 #31
Она не может возвращать ссылку на оригинал, сама строка может хранится в контейнере std::string блоками в разных участках памяти, что и писали выше. std::string::c_str() лишь генерирует Си строку, указателем на которую можно безопасно пользоваться до любого изменения строки. Вот тот при мер кода, который я так же приводил в пример на 2 странице:
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 = "qwerty";
   
   cstr2 = str.c_str();
   
   std::cout << '\n' << str << '\n' << cstr1 << '\n' << cstr2 << std::endl;
   
   return 0;
}
Вот вывод.
0
taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
16.06.2012, 15:00  [ТС] #32
Цитата Сообщение от Toshkarik Посмотреть сообщение
Она не может возвращать ссылку на оригинал, сама строка может хранится в контейнере std::string блоками в разных участках памяти, что и писали выше.
И что?
Цитата Сообщение от Toshkarik Посмотреть сообщение
std::string::c_str() лишь генерирует Си строку, указателем на которую можно безопасно пользоваться до любого изменения строки.
си строка есть строка символов, хранимых подряд в одном месте и с терминальным нолём. Возвращается не список, не дерево, не массив и не иной контейнер си строк а сама строка. Значит после std::string::c_str() такая строка существует. Почему бы теперь ни назначить внутренний указатель на строку уже на неё? Раз уж память выделена. То есть сначала меняем размещение оригинал и ставим терминальный ноль, а потом уже возвращаем указатель. При этом длина строки продолжает храниться в готовом виде. С другой стороны, можно вернуть копию и при этом указатель на неё запомнить внутри, а при повторном std::string::c_str() верунть второй раз ту же копию. Я свой кривостринг сделала сначала с возвратом оригинала, причём, данные всегда хранились в виде комбинации динамической си строки (с терминальным нолём), её длины в отдельном поле.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class TSting
{
 protected:
  char *data; // нуль-терминальная строка
  unsigned long int count; // длина строки
 public:
  TString ();
  TString (TString &s);
  TString (char *s);
 ~TString ();
 TString operator +=(TString &s);
 TString operator +=(char *s);
 TString operator +=(char c);
 TString operator +(TString &s);
 TString operator +(char *s);
 TString operator +(char c);
 TString operator =(TString &s);
 TString operator =(char *s);
 TString operator =(char c);
 char &operator [] (unsigned long int number); // номирация с ноля
 unsigned long int Length();
 operator  unsigned long int (); //Тоже возвращает длину строки
};
при запросе длины строки, она возвращается из поля count. При любой операции строки, которая может изменить её длину, count обновляется. Если к строке TString добавляется си строка, то сначала в цикле считается её длина, потом выделяется память, потом count увеличивается на длину слагаемого оператором += и только потом происходит копирование из обеих строк, сначала из старого TString. Если строка TString созданётся на основе си строки, или ей присваивается си строка, то сначала счёт символов в цикле, потом выделение памяти, потом копирование, потом присваивание длины. В остальных случаях сразу выделение памяти, потом копирование, потом += для увеличения count. Потом переписал на возврат копии, за удаление которой отвечала вызывающая функция. Каждый раз возвращалась новая копия, но данные всё равно хранились подряд и с теримнальным нолём на конце. И покажи ка цитату из стандарта, гарантирующую, что символы стринга хранятся в разрозненных кусках. Если нет гарантии обратного, то это ещё ничего не значит.
0
Toshkarik
1141 / 858 / 51
Регистрация: 03.08.2011
Сообщений: 2,386
Завершенные тесты: 1
16.06.2012, 15:07 #33
Вы покажите цитату где я утверждал, что он всегда будет хранится в разных местах памяти? Ваш пост если честно ни о чем. Ваша реализация кого то там класса, это Ваша реализация, и я почти уверен, что она отличается от всех тех, что используют существующие компиляторы. Я могу привести другую цитату:
Generates a null-terminated sequence of characters (c-string) with the same content as the string object and returns it as a pointer to an array of characters.
0
taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
16.06.2012, 15:24  [ТС] #34
Цитата Сообщение от Toshkarik Посмотреть сообщение
Вы покажите цитату где я утверждал, что он всегда будет хранится в разных местах памяти?
Читай:
Цитата Сообщение от Toshkarik Посмотреть сообщение
на не может возвращать ссылку на оригинал, сама строка может хранится в контейнере std::string блоками в разных участках памяти,
Если не может вернуть из-за размещения, значит оно всегда такое. Иначе можно привести к подходящему размещению и потом вернуть указатель на внутренние данные.

Добавлено через 2 минуты
Цитата Сообщение от Toshkarik Посмотреть сообщение
и я почти уверен, что она отличается от всех тех, что используют существующие компиляторы.
Я сам в этом уверен. Но тем не менее, отдельные аспекты класса могли придти в голову не только мне. На свой класс я ссылаюсь только как пример принципиальной возможности возвращать указатель хоть на оригинал, хоть на копию. И при возврате указателя на оригинал разработчики класса могут специально позаботиться обо всех особенностях размещения, чтоб они этот фокус позволяли. Мораль проста: если указатель на оригинал смог вернуть даже я всего через 3 месяца от начала изучения языка, то уж тем более это мог сделать, например, Страуструп, если бы счёл это целесообразным.
0
Toshkarik
1141 / 858 / 51
Регистрация: 03.08.2011
Сообщений: 2,386
Завершенные тесты: 1
16.06.2012, 15:26 #35
Цитата Сообщение от taras atavin Посмотреть сообщение
сама строка может хранится в контейнере std::string блоками в разных участках памяти,
Что не понятного из этой фразы? Или Вы считаете, что должна быть проверка, находится ли строка в одном месте или кусками, и на основании этого возвращать указатель? И опять же:
Цитата Сообщение от Toshkarik Посмотреть сообщение
Generates a null-terminated sequence of characters (c-string) with the same content as the string object and returns it as a pointer to an array of characters.
Функция генерирует си-строку...
0
taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
16.06.2012, 15:44  [ТС] #36
Цитата Сообщение от Toshkarik Посмотреть сообщение
Что не понятного из этой фразы?
"Может хранить" не значит, что именно так она и хранит, фраза лишь утверждает, что нет гарантии обратного. Но обратное всё же возможно. И если оно для его то нудно разработчикам класса, то именно так и будет сделано. Можно даже сделать так, что по дефолту строка разрорвана на фрагменты, а sts::string::c_str() сначала собирает их в один во внутреннем представлении (ему же всё равно сначала надо собрать их в один), а только потом возвращает указатель и после него до следующего изменения строка уже хранится единым блоком до следующего своего изменения. Как вариант - можно хранить список нультерминальных массивов символов с индивидуальными полями длины и ещё общим полем длины, а по sts::string::c_str() приводить его к одному нультерминальному массиву символов через двойной указатель с дублированным полем полной длины.

Добавлено через 3 минуты
Гипотез можно строить много, без строгих формулировок в стандарте (а "может" - не строгая, так как ничего не гарантирует) только листинг и спецификация реализации могут пролить свет на то, как в действительности хранятся данные и что возвращается.

Добавлено через 2 минуты
Цитата Сообщение от Toshkarik Посмотреть сообщение
Функция генерирует си-строку...
Эйси. Но "генерирует копию данных в виде си строки" и "генерирует си строку и заменяет ею текущее внутреннее представление" - далеко не одно и тоже, но то и то будет "генерирует си строку".
0
Toshkarik
1141 / 858 / 51
Регистрация: 03.08.2011
Сообщений: 2,386
Завершенные тесты: 1
16.06.2012, 15:52 #37
Да о чем Вы вообще? Куда Вас понесло?
Цитата Сообщение от taras atavin Посмотреть сообщение
не значит, что именно так она и хранится,
Я и написал, что МОЖЕТ хранить, и не писал обратного, не нужно пожалуйста осознанно коверкать смысл фразы.
Цитата Сообщение от taras atavin Посмотреть сообщение
И если оно для его то нудно разработчикам класса
Вы сами эту фразу поняли?

Все выше Вами описанное c_str() не обязана делать, в ее задачу лишь входит генерация Си-строки, и возвращение указателя на нее, ни слова о том, что она должна как то объединять внутреннее представление строки, или вообще делать что то еще с объектом. Так зачем же разработчикам усложнять себе жизнь?
Цитата Сообщение от taras atavin Посмотреть сообщение
Но "генерирует копию данных в виде си строки" и "генерирует си строку и заменяет ею текущее внутреннее представление" - далеко не одно и тоже, но то и то будет "генерирует си строку".
Вы хоть читали полностью эту цитату? Покажу 3 раз:
Generates a null-terminated sequence of characters (c-string) with the same content as the string object and returns it as a pointer to an array of characters.

Добавлено через 3 минуты
PS: синоним слова генерировать - создавать. Функция создает массив символов, ограниченный ноль-символом, и по содержанию идентичный строке-объекту.
0
taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
16.06.2012, 15:59  [ТС] #38
Цитата Сообщение от Toshkarik Посмотреть сообщение
Все выше Вами описанное c_str() не обязана делать, в ее задачу лишь входит генерация Си-строки, и возвращение указателя на нее, ни слова о том, что она должна как то объединять внутреннее представление строки, или вообще делать что то еще с объектом. Так зачем же разработчикам усложнять себе жизнь?
Ну она же всё равно должна объединить данные объекта.

Добавлено через 1 минуту
Цитата Сообщение от Toshkarik Посмотреть сообщение
PS: синоним слова генерировать - создавать.
Думаешь, я этого не понимаю?

Добавлено через 51 секунду
Модераторы, прикройте эту тему с хвостом ни о чём, а то она давно в офтоп свалилась.
0
Toshkarik
1141 / 858 / 51
Регистрация: 03.08.2011
Сообщений: 2,386
Завершенные тесты: 1
16.06.2012, 16:00 #39
Она не должна ничего объединять. Она должна создать массив символов ( Си-строку ), идентичный по содержанию string-объекту.
0
ForEveR
В астрале
Эксперт С++
7979 / 4738 / 321
Регистрация: 24.06.2010
Сообщений: 10,543
Завершенные тесты: 3
16.06.2012, 17:05 #40
5 The char-like objects in a basic_string object shall be stored contiguously. That is, for any basic_string
object s, the identity &*(s.begin() + n) == &*s.begin() + n shall hold for all values of n such that 0
<= n < s.size().
Итого - по кускам строка хранится НЕ может. Она обязана хранится в непрерывной области памяти.

6 References, pointers, and iterators referring to the elements of a basic_string sequence may be invalidated
by the following uses of that basic_string object:
— as an argument to any standard library function taking a reference to non-const basic_string as an
argument.234
— Calling non-const member functions, except operator[], at, front, back, begin, rbegin, end, and
rend.
Итого при вызове не константных функций, за исключением некоторых - итераторы, указатели могут стать не валидными.

const charT* c_str() const noexcept;
const charT* data() const noexcept;
1 Returns: A pointer p such that p + i == &operator[](i) for each i in [0,size()].
2 Complexity: constant time.
3 Requires: The program shall not alter any of the values stored in the character array.
Итого - не генерируется никакой новой строки.

Что, в стандарт сложно заглянуть?

Добавлено через 26 минут
Хотя все понятно. В стандарте С++98 ничего такого не описано.
2
Jupiter
16.06.2012, 17:14     std::string в char*
  #41

Не по теме:

когда сам садишься писать тот же string начинаешь понимать, а нафига его делать непоследовательно!?

0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
16.06.2012, 17:14
Привет! Вот еще темы с ответами:

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*. а мне нужно получить ...


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

Или воспользуйтесь поиском по форуму:
41
16.06.2012, 17:14
Ответ Создать тему
Опции темы

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