Що таке функція c_str у c ++


78

Я щойно почав читати C ++ і виявив, що c ++ має розширені функції для маніпулювання рядками, яких у C немає. Я читаю цю функцію і натрапив, c_str()і з того, що я розумію, це c_strперетворення рядка, який може закінчуватися нулем, а може бути, не в рядок, закінчений нулем. Чи правда?

Хто-небудь може підказати мені якийсь приклад, щоб я міг зрозуміти використання функції c_str ??

Відповіді:


92

c_strповертає a, const char*що вказує на рядок із нульовим закінченням (тобто рядок у стилі C). Це корисно, коли ви хочете передати "вміст" an std::stringфункції функції, яка передбачає роботу з рядком у стилі C.

Наприклад, розглянемо цей код:

std::string str("Hello world!");
int pos1 = str.find_first_of('w');

int pos2 = strchr(str.c_str(), 'w') - str.c_str();

if (pos1 == pos2) {
    printf("Both ways give the same result.\n");
}

Побачте це в дії .

Примітки:

Це не зовсім вірно, оскільки std::string(на відміну від рядка С) може містити \0символ. Якщо це станеться, код, який отримує повернене значення, c_str()буде обдурений, думаючи, що рядок коротший, ніж є насправді, оскільки він буде інтерпретувати \0як кінець рядка.


1
Дуже цікавий момент, який ви зробили в примітках: що я хотів би знати, якщо std :: рядок вже міститься \ 0, тоді c_str також додається \ 0 в кінці рядка ??
Amit Singh Tomar

3
@AmitSinghTomar: Так, отже, у вас буде два нульові байти - один, який є законно частиною рядка, і той, який повинен бути нульовим термінатором. Але функція c-style, яка отримує покажчик, цього не знає.
Джон

Примітка: ряд C-API вимагатиме два аргументи ( char const*, size_t), другий, звичайно, розмір.
Matthieu M.

Це не працює: string str("0.85"); newVolume = _tstof((TCHAR*)str.c_str());як я можу перетворити вхід 0,85 TCHAR * argv [] у це?

1
@YumYumYum ви не можете використовувати std::stringразом із матеріалами TCHAR, суть TCHAR полягає в автоматичному перемиканні між char / wchar, поки std::stringпрацює лише з точки зору char. Вам доведеться використовувати відповідну абстракцію, або просто просто не використовувати TCHAR взагалі і завжди робити збірку Unicode.
Джон

56

У C ++ ви визначаєте свої рядки як

std::string MyString;

замість

char MyString[20];.

Під час написання коду на C ++ ви стикаєтесь із деякими функціями C, які вимагають рядка C як параметр.
Як нижче:

void IAmACFunction(int abc, float bcd, const char * cstring);

Зараз є проблема. Ви працюєте з C ++ і використовуєте std::stringрядкові змінні. Але ця функція C запитує рядок C. Як конвертувати вашstd::string на стандартний рядок С?

Подобається це:

std::string MyString;
// ...
MyString = "Hello world!";
// ...
IAmACFunction(5, 2.45f, MyString.c_str());

Це те, що c_str()для.

Зверніть увагу, що для std::wstringрядків c_str()повертає a const w_char *.


8

Більшість функцій OLD c ++ та c, коли мають справу з рядками, використовують const char*.
За допомогою STL та std::string, string.c_str()вводиться можливість конвертувати з std::stringв const char*.

Це означає, що якщо ви обіцяєте не змінювати буфер, ви зможете використовувати вміст рядка лише для читання. PROMISE = const char *


@ Не існує такого поняття, як stl::string. Насправді навіть немає такого поняття, як "STL", крім як десь у музеї.
Kerrek SB

6

c_str () перетворює рядок С ++ у рядок у стилі С, який по суті є масивом байтів, що закінчується нулем. Ви використовуєте його, коли хочете передати рядок С ++ у функцію, яка очікує рядок у стилі С (наприклад, багато Win32 API, функції стилю POSIX тощо).


3
Я б не сказав "навернених". Навпаки, функція "забезпечує доступ" до відповідного масиву символів, призначеного лише для читання - швидше за все, масиву, який завжди був там для реалізації std::string.
Kerrek SB

5

Він використовується для забезпечення std::stringвзаємодії з кодом C, який вимагає завершення з нулем char*.


5

У програмуванні на C / C ++ існує два типи рядків: рядки C та стандартні рядки. За допомогою <string>заголовка ми можемо використовувати стандартні рядки. З іншого боку, рядки C - це просто масив звичайних символів. Отже, для того, щоб перетворити стандартний рядок у рядок C, ми використовуємо c_str()функцію.

наприклад

// a string to a C-style string conversion//

const char *cstr1 = str1.c_str();
cout<<"Operation: *cstr1 = str1.c_str()"<<endl;
cout<<"The C-style string c_str1 is: "<<cstr1<<endl;
cout<<"\nOperation: strlen(cstr1)"<<endl;
cout<<"The length of C-style string str1 = "<<strlen(cstr1)<<endl;

І результат буде,

Operation: *cstr1 = str1.c_str()
The C-style string c_str1 is: Testing the c_str 
Operation: strlen(cstr1)
The length of C-style string str1 = 17

1

О, тут слід додати мій власний вибір, ви будете використовувати це, коли кодуєте / декодуєте деякий рядок obj, який ви передаєте між двома програмами.

Скажімо, ви використовуєте base64encode якийсь масив у python, а потім ви хочете декодувати його в c ++. Як тільки у вас є рядок, який ви декодуєте з base64decode в C ++. Для того, щоб повернути його до масиву float, тут вам потрібно лише зробити

float arr[1024];
memcpy(arr, ur_string.c_str(), sizeof(float) * 1024);

Я вважаю, що це досить поширене використання.


Цей тип коду не є портативним (ендіанс та формат плаваючого середовища серед інших)
Phil1970,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.