C ++: «Мой текст» - это std :: string, a * char или c-string?

Я только что сделал то, что кажется распространенной ошибкой новичка :

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

 #include 
 int main() {
      using namespace std;
      ifstream inf("file.txt");
      // (...)
 }  

Во-вторых мы пытаемся использовать нечто похожее в нашем коде, которое выглядит примерно так:

#include 
int main() {
    using namespace std;
    std::string file = "file.txt"; // Or get the name of the file 
                                   // from a function that returns std::string.
    ifstream inf(file);
    // (...)
}

В-третьих, Разработчик новичка озадачен каким-то загадочным сообщением об ошибке компилятора.

Проблема в том, что ifstream принимает const * char в качестве аргумента конструктора.

Решение состоит в том, чтобы преобразовать std :: string в const * char .

Теперь реальная проблема заключается в том, что для новичка, file.txt или Подобные примеры, приведенные почти во всех уроках, очень похожи на std :: string.

Итак, «мой текст» это std :: string, c-string или * char или это зависит от контекста?

Можете ли вы привести примеры того, как «мой текст» будет интерпретироваться по-разному в зависимости от контекста?

Решение состоит в том, чтобы преобразовать std :: string в const * char .

Теперь реальная проблема заключается в том, что для новичка, file.txt или Подобные примеры, приведенные почти во всех уроках, очень похожи на std :: string.

Итак, «мой текст» это std :: string, c-string или * char или это зависит от контекста?

Можете ли вы привести примеры того, как «мой текст» будет интерпретироваться по-разному в зависимости от контекста?

Решение состоит в том, чтобы преобразовать std :: string в const * char .

Теперь реальная проблема заключается в том, что для новичка, file.txt или Подобные примеры, приведенные почти во всех уроках, очень похожи на std :: string.

Итак, «мой текст» это std :: string, c-string или * char или это зависит от контекста?

Можете ли вы привести примеры того, как «мой текст» будет интерпретироваться по-разному в зависимости от контекста?

или это зависит от контекста?

Можете ли вы привести примеры того, как «мой текст» будет интерпретироваться по-разному в зависимости от контекста?

или это зависит от контекста?

Можете ли вы привести примеры того, как «мой текст» будет интерпретироваться по-разному в зависимости от контекста?

[Редактировать: я думал, что приведенный выше пример сделал бы это очевидным, но, тем не менее, я должен был быть более точным: я имею в виду тип любой строки, заключенной в двойные кавычки, т.е. «myfilename.txt», а не значение слова «строка».]

Спасибо.

9
задан Community 23 May 2017 в 12:13
поделиться

7 ответов

Итак, "строка" - это std :: string, c-string или * char, или это зависит от контекста?

  • Ни C, ни C ++ не имеют встроенного строкового типа данных, поэтому любые строки в двойных кавычках в вашем коде по сути являются const char * (или const char [] , чтобы быть точный). «Строка C» обычно относится к этому, особенно к массиву символов с нулевым ограничителем.
  • В C ++ std :: string - это вспомогательный класс, который превращает необработанную строку в объект. Используя это, вы можете избежать необходимости самостоятельно выполнять (беспорядочную) арифметику указателей и перераспределение памяти.
  • Большинство стандартных библиотечных функций по-прежнему принимают только параметры char * (или const char * ).
  • Вы можете неявно преобразовать char * в std :: string , потому что у последнего есть конструктор для этого.
  • Вы должны явно преобразовать std :: string в const char * с помощью метода c_str () .

Спасибо Clark Gaebel за указание на const ness, а также jalf и GMan за упоминание, что это на самом деле массив.

10
ответ дан 4 December 2019 в 08:49
поделиться
std::string file = "file.txt"; 

Правая часть = содержит (необработанный) строковый литерал (например, байтовую строку с завершающим нулем). Его эффективный тип - массив const char .

= здесь - хитрый пони: никакого назначения не происходит. Класс std :: string имеет конструктор, который принимает указатель на char в качестве аргумента, и он вызывается для создания временного std :: string и используется для копирования-конструкции (с использованием ctor копирования std :: string ) объект файл типа std :: string .

Однако компилятор может исключить объект копирования и напрямую создать экземпляр файла.

Однако обратите внимание, что std: string - это не то же самое, что строка в стиле C с завершающим нулем. Это даже не обязательно должно быть завершено нулем.

ifstream inf("file.txt");

Класс std :: ifstream имеет ctor, который принимает const char * , а переданный ему строковый литерал распадается до указателя на первый элемент строки.

Следует помнить следующее: std :: string обеспечивает (почти бесшовное) преобразование из строк в стиле C. Вам нужно найти подпись функции, чтобы узнать, передаете ли вы const char * или std :: string (последнее из-за неявных преобразований).

3
ответ дан 4 December 2019 в 08:49
поделиться

Для использования правильной формулировки (как указано в стандарте языка C ++) строка является одной из разновидностей std :: basic_string (включая std :: string) из главы 21.3 «Строковые классы» (как в C ++ 0x N3092), в то время как аргумент конструктора ifstream - NTBS (последовательность байтов с завершающим нулем)

Чтобы процитировать, C ++ 0x N3092 27.9.1.4 / 2.

basic_filebuf * open (const char * s, ios_base :: openmode mode);

...

открывает файл, если возможно, с именем NTBS s

0
ответ дан 4 December 2019 в 08:49
поделиться

Стандартная библиотека C ++ предоставляет класс std :: string для управления и представления последовательностей символов. Он инкапсулирует управление памятью и большую часть времени реализуется как C-строка; но это деталь реализации. Он также предоставляет процедуры управления для общих задач.

Тип std :: string всегда будет таким (например, у него нет оператора преобразования в char *, поэтому у вас есть метод c_str ()), но он может быть инициализирован или назначен C -строка (символ *).

С другой стороны, если у вас есть функция, которая принимает в качестве параметра std :: string или const std :: string &, вы можете передать ей c-строку (char *), и компилятор построит std :: string на месте для вас. Это было бы разной интерпретацией в зависимости от контекста, как вы это выразились.

1
ответ дан 4 December 2019 в 08:49
поделиться

"myString" является строковым литералом и имеет тип const char[9], массив из 9 констант char. Обратите внимание, что в нем достаточно места для нулевого терминатора. Итак, "Привет" является const char[3] и так далее.

Это почти всегда верно, без двусмысленности. Однако при необходимости const char[9] распадается на const char*, указывающий на его первый элемент. И std::string имеет неявный конструктор, который принимает символ const*. Поэтому, хотя он всегда начинается как массив char, он может стать другими типами, если вам это нужно.

Обратите внимание, что строковые литералы обладают уникальным свойством, что const char[N] также может распадаться на char*, но это поведение устарело. Если вы попытаетесь изменить базовую строку таким образом, вы получите неопределенное поведение. Это просто не очень хорошая идея.

7
ответ дан 4 December 2019 в 08:49
поделиться

Как можно чаще это должно означать std :: string (или альтернативу, например wxString , QString и т. Д., Если вы используете фреймворк, который предоставляет это. Иногда у вас нет реального выбора, кроме как использовать последовательность байтов с завершающим NUL, но обычно вы хотите избежать этого, когда это возможно.

В конечном итоге, просто нет четкой, однозначной терминологии. Такова жизнь.

0
ответ дан 4 December 2019 в 08:49
поделиться

Итак, является ли «строка» std::string, c-строкой или char*, или это зависит от контекста?

Это полностью зависит от контекста. :-) Добро пожаловать в C++.

Строка C — это строка с завершающим нулем, которая почти всегда совпадает с char*.

В зависимости от используемых вами платформ и фреймворков может быть еще больше значений слова «строка» (например, оно также используется для обозначения QString в Qt или CString. в МФЦ).

2
ответ дан 4 December 2019 в 08:49
поделиться
Другие вопросы по тегам:

Похожие вопросы: