Я запутался в инициализации строки. Я считаю, что следующее:
Дело 1:
char s1[100] = { "apple" };
Вариант 2:
char s1[100];
s1 = "apple";
case1 компилируется нормально, однако case2 получает ошибку. Компилятор говорит, что я пытаюсь назначить char [5] char [100]... Не могли бы вы пояснить разницу между двумя случаями?
Базовые массивы (так называемые необработанные массивы) не поддерживают прямое назначение.
Ваш случай 1 не присваивается: инициализация.
Стандартная библиотека предлагает std::array
который по существу обертывает необработанный массив в struct
и, следовательно, присваивается.
Однако, для видимой цели вашего кода, массив был бы неправильным выбором.
Вместо этого используйте std::string
, которая поддерживает как инициализацию, так и назначение строкового литерала.
Пример (include <string>
):
using std::string;
string s1 = "apple";
string s2;
s2 = apple;
случай 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
, который работает более интуитивно (вам нужно будет #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