Помогите с указателями

Вот программа

#include <iostream>

using namespace std;

int main() {
    char *str = "String";
    char *pstr = str;
    *pstr = '-';   // здесь вылетает ((
    cout << str << endl;
}

пробовала str вынести из функции main — та же фигня.
Почему access violation?? str вроде обычный указатель на char без всяких const.
Как поправить?
Надо что бы в программе были забиты строки, а во время работы чтобы программа меняла эти строки и выводила на экран.
Пока сделала через копирование во временный буфер. Но хотелось бы менять строки напрямую.

str вроде обычный указатель на char без всяких const.

Во-первых, такой код давно не валиден для C++. В C++ там должен быть const.

Почему access violation?

Потому что строковые литералы будут сохранены где-то в read-only памяти (а то и еще круче), писать в которую простому смертному запрещено.

Надо что бы в программе были забиты строки, а во время работы чтобы программа меняла эти строки и выводила на экран.

Завести свой массив не судьба?

char str[] = «String»;

Во-первых, такой код давно не валиден для C++. В C++ там должен быть const.

Компилятор ни чего не говорит на счёт невалидности кода. Даже предупреждений не дает.
А почему зтот код не валиден? Это где-то написано? в стандарте например?

Завести свой массив не судьба?
char str[] = «String»;

О, спасибо, так работает.
Я думала (так объясняли), что

char * const str = "String";
char str[] = "String";

это одно и то же.
Я даже в программе специально const убрала, что бы не смущщал.

А если делать массив, то как тогда сделать массив строк?
Если так:

char *str[] = {
    "Str 1",
    "String 2",
    "Long string 3"
};

то получается как и с

char *str = "String";

а написать что-то типа char str[][] нельзя.
Можно char str[][20], но тогда под короткие строки выделяется лишнее место.
Что посоветуете?

Что посоветуете?

Использовать std::string или std::string_view (c++17).

но тогда под короткие строки выделяется лишнее место.

Что-то мне подсказывает, что это экономия на спичках.

Компилятор ни чего не говорит на счёт невалидности кода.

Эт какой это? Ежели gcc(mingw)/clang, то ключ -pedantic-errors скормите ему.

Это где-то написано? в стандарте например?

В нем, родимом. Емнип, то в c++98 такое преобразование уже было объявлено устаревшим, а из c++11 — удалено вовсе.

Вообще-то я победила проблему. Вот таким неэлегантным способом:

#include <iostream>

using namespace std;

char
s1[] = "Str 1",
s2[] = "String 2",
s3[] = "Long string 3";

char *str[] = { s1, s2, s3 };

int main() {
    char *pstr = str[1];
    *pstr = '-';
    for (int i = 0; i < sizeof(str) / sizeof(str[0]); i++)
        cout << str[i] << endl;
}

Если кто подскажет как это сделать без определения лишних переменных, буду признательна.

Вопрос даже не в экономии.
Я пока не знаю какой длины будет самая длинная строка. А в описании массива это надо указать. Да и подсчитывать букавки в строке вручную как-то не хочется.
Но все равно спасибо!

Компилятор Visual Studio 2017. Настройки проекта по умолчанию.

Если кто подскажет как это сделать без определения лишних переменных, буду признательна.

Можно что-нибудь придумать на макросах и шаблонах, но это будет значительно сложнее.

Я пока не знаю какой длины будет самая длинная строка.

Тогда почему не std::string?

Ответить

Вы можете использовать разметку markdown для оформления комментариев и постов. Используйте функцию предпросмотра для проверки корректности разметки.

Пожалуйста, оформляйте исходный код в соответствии с правилами разметки. Для того, чтобы вставить код в комментарий, скопируйте его в текстовое поле ниже, после чего выделите то, что скопировали и нажмите кнопку «код» в панели инструментов. Иначе ваш код может принять нечитаемый вид.

Либо производите оформление кода вручную, следующим образом:

``` #include <iostream> using namespace std; int main() { // ... } ```

Предпросмотр сообщения

Ваше сообщение пусто.