Присвоение строки массиву char

0

Я запутался в инициализации строки. Я считаю, что следующее:

Дело 1:

char s1[100] = { "apple" };

Вариант 2:

char s1[100];
s1 = "apple";

case1 компилируется нормально, однако case2 получает ошибку. Компилятор говорит, что я пытаюсь назначить char [5] char [100]... Не могли бы вы пояснить разницу между двумя случаями?

Теги:
string

2 ответа

3
Лучший ответ

Базовые массивы (так называемые необработанные массивы) не поддерживают прямое назначение.

Ваш случай 1 не присваивается: инициализация.

Стандартная библиотека предлагает std::array который по существу обертывает необработанный массив в struct и, следовательно, присваивается.

Однако, для видимой цели вашего кода, массив был бы неправильным выбором.

Вместо этого используйте std::string, которая поддерживает как инициализацию, так и назначение строкового литерала.


Пример (include <string>):

using std::string;
string s1 = "apple";
string s2;

s2 = apple;
3

Объяснение текущего кода

случай 1 является законным способом инициализации s1, причем 'a' переходит в [0], 'p' в [1] и [2], 'l' в [3], 'e' в [4], а остальные установлен на 0 (ASCII NUL - см. http://en.wikipedia.org/wiki/ASCII).

case 2 пытается присвоить один массив другому (другого размера в соответствии с сообщением), что не является законным в C++. Для этого вы должны использовать strcpy(s1, "apple"), хотя он немного отличается от поведения: он установит только s1[5] в 0/NUL, а [6] не будет затронут (если s1 находится в стеке или куче они будут неинициализированы, и чтение из них будет неопределенным поведением). Большинство вещей, которые вы хотите сделать с s1, не выиграют от инициализации [6] далее....

Интуитивная альтернатива: 'std :: string'

Возможно, лучшим решением является переход на std::string, который работает более интуитивно (вам нужно будет #include <string> поверх вашей программы). Синтаксис для случая 1 будет несколько иным: std::string s1 = "apple"; , или - если у вас есть компилятор C++ 11 - std::string s1 { "apple" }; ,

Считываемые буферы против указателей на строковые литералы

Заметим также, что в вашем вопросе char s1[100] создает массив из 100 символов, который вы можете читать и писать, а затем копируете из литерала строки только для чтения ("const") в этот записываемый буфер. Если вы просто хотите отслеживать текст (например, это "яблоко", а не "оранжевое", которое может быть скопировано в s1 позже), без необходимости дальнейшего изменения текста, вы можете использовать const char* для хранения адрес строкового литерала:

const char* p_s1 = "apple";
if (f()) p_s1 = "orange";
std::cout << "go eat an " << p_s1 << '\n';

В качестве примера const типа строковых литералов, с константой const char* p_s1 выше, вы не можете изменять строковые литералы, указанные в:

#include <cctype>
...
p_s1[0] = std::toupper(p_s1[0]);   // oops! p_s1[0] inside string literal - mustn't write

Если вы застряли с char s1[100]; вы можете сделать:

s1[0] = std::toupper(s1[0]);       // ok
  • 1
    Ну, «другого размера», прямое назначение одного и того же размера массива также недействительно.
  • 0
    Как насчет char s1 [100] = "apple"; (без брекетов)? Странно, компилятор не жалуется.
Показать ещё 3 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню