Qator mag'lubiyatidan string qatorini qanday yaratiladi?

Men yozadigan, ammo doimiy ravishda ishga tushiriladigan unittests uchun char * values ​​[] ni yaratishga harakat qilaman. Undan tashqari, ISO C ++ uni ogohlantirmoqda:

char* single[1];
single[0] = "foobar";

Men, albatta, ishlamayotgan quyidagi narsani sinab ko'rdim:

std::string executable = "foobar";
std::array data;//Error: size not known at compile time
std::copy(executable.begin(), executable.end(); data.data());

char* single[1];
single[0] = data.data();

Quyidagi yo'l bo'lishi kerak:

std::array data = { "foobar" };
char* single[1];
single[0] = data.data();
1
C ++ satrida matnlar doimiy belgilar majmuasi. Ya'ni, masalan, const char * single [1] yozishingiz kerak; yakka [0] = "foobar";
qo'shib qo'ydi muallif Vlad from Moscow, manba
@VladfromMoscow Lekin men char ** kerak, shuning uchun men ma'lumotlarni erkin boshqarishga harakat qilaman. Konstness yo'lda.
qo'shib qo'ydi muallif aggsol, manba

6 javoblar

Avtomobil qutisiga to_array qo'shishingizni tavsiya qilaman . Shunda siz oddiygina yozishingiz mumkin

auto data = to_array("foobar");
char* single[1];
single[0] = data.data();
4
qo'shib qo'ydi
Bu ajoyib topilma, juda yomon, hali standart emas.
qo'shib qo'ydi muallif aggsol, manba
std::string foo = "foobar";
std::vector data(foo.data(), foo.data()+foo.size()+1u);
char* single[1];
single[0] = data.data();

Std :: stringni qanday qilib aylantirish mumkin char * char yoki * char * uchun bosing.

Ushbu naqshni qayta ko'rib chiqadigan bo'lsa, siz aylantirishning bir nechta funksiyasidan foydalanishingiz mumkin:

template
std::vector literal_vector(CharT const (&a)[N])
{
    return std::vector(&a[0], (&a[0]) + N);
}

undan keyin

std::vector lv = literal_vector("Hello");
single[0] = lv.data();
3
qo'shib qo'ydi

Savolingiz c ++ 1z sifatida belgilanmagan bo'lsa-da, std :: string data </​​code> funktsiyasining konstnessni cheklashi eskirgan. Standartning joriy ishchi loyihasi ( N4618 ), C ++ 17 sifatida nashr etilishi kerak. [Basic.string] da, ikkalasini ham topishingiz mumkin:

  const charT * ma'lumotlar() const noexcept;
charT * ma'lumotlar() noexcept;
 
-ni tanlang

Sizning kompilyatoringiz, ehtimol, derleyici bayrog'iga -std = c ++ 1z yoki shunga o'xshash bo'lishi kerak. Agar shunday bo'lsa, siz yozishingiz kerak:

std::string executable = "foobar";
char *single[1];
single[0] = executable.data();
3
qo'shib qo'ydi
Bu men istagan minimal yondashuv va umid qilamanki yaqin orada foydalanishadi.
qo'shib qo'ydi muallif aggsol, manba

Bu erda siz yo'llarni tortib oldingiz, ikkalasi ham memcpy dan foydalanmoqdalar.

  1. Dinamik xotiradan foydalanish.
  2. Statik xotiradan foydalanish.
 

    using namespace std;

    #define MAX_BUFFER_SIZE 250
    int main()
    {
        const char* myData = "This is My Data";

        int sizeOfmydata = std::strlen(myData);;

        //1.- Dinamic Memory
        char* data1 = new char[sizeOfmydata];
        std::memcpy(data1, myData, sizeOfmydata);

        //2.- Static Memory
        char data2[MAX_BUFFER_SIZE];
        memset(data2, '\0', MAX_BUFFER_SIZE);
        std::memcpy(data2, myData, sizeOfmydata);


        delete[] data1;
        return 0;
    }

1
qo'shib qo'ydi

You can use std::vector to store your data, and use c_str() of std::string to parse your string to char*

1
qo'shib qo'ydi
Ehtimol xavfli va UB bo'lgan.
qo'shib qo'ydi muallif Pixelchemist, manba
c_str() kodi char * emas, balki const char *
qo'shib qo'ydi muallif aggsol, manba
@Pixelchemist UB nima degani?
qo'shib qo'ydi muallif aggsol, manba
Buni @pergy kabi o'zgartirishingiz mumkin
qo'shib qo'ydi muallif OrMiz, manba

Bu ozgina bo'lsa-da, lekin kerakli narsani qilmoqdadir. Bu fayl foo.cpp :

#include 
#include 
#include 
#include 
#include 

int main(int argc, char* argv[])
{
    std::vector strings = {"foobar", "barbaz"};

    char* values[strings.size()];

    for (int i = 0; i < strings.size(); ++i) {
        values[i] = new char[strings[i].size() + 1];
        std::copy(strings[i].cbegin(), strings[i].cend(), values[i]);
        values[strings[i].size()] = '\0';
    }

    for (int i = 0; i < strings.size(); ++i) {
        printf("%s\n", values[i]);
    }

    return 0;
}

Keyin:

$ make foo
g++     foo.cpp   -o foo
$ ./foo
foobar
barbaz

char * qatorining har bir elementini delete va, ehtimol, std :: string dan nusxa ko'chirish uchun pastadir qo'yish kerak. char * va hokazo.

PS: Bu echim, kimdir allaqachon bog'langan bo'lgan bu javobga »mos tushadi .... Boshqa javobda batafsil ma'lumot bor . Bu sizning savolingiz duplikat degan ma'noni anglatadimi? Tajribali foydalanuvchilar qaror qabul qilishga ruxsat beraman.

0
qo'shib qo'ydi
Yo'q, char * val [] yoki char ** val ni xohlayman, chunki men qatorni va uning qiymatlarini o'zgartirish kerak.
qo'shib qo'ydi muallif aggsol, manba
noto'g'ri tushunish uchun uzr so'raymiz
qo'shib qo'ydi muallif user7473772, manba
@aggsol Endi men yaxshi deb o'ylayman :) hech bo'lmaganda barcha yozuvlarni yozish oson va keyin siz ularni new bilan yaratgan xotiraga nusxa olasiz, bu siz istamasangiz qochib qutulaman const ness
qo'shib qo'ydi muallif user7473772, manba