2017-03-16 25 views
-1

書かれますが定数から初期化される私のunittestsのためにchar* values[]を作成しようとしています。素朴な方法は、ISO C++がそれを禁じていることを警告がスローされます。文字列定数から文字配列を作成する方法は?

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

私は明らかに動作しないことが次のことを試してみました:

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

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

のような方法があるに違いありません:

std::array<char> data = { "foobar" }; 
char* single[1]; 
single[0] = data.data(); 
+2

C++の文字列定数は定数文字配列です。ですから、例えばconst char * single [1]と書く必要があります。 single [0] = "foobar"; –

+0

@VladfromMoscowしかし、データを自由に操作できるように 'char ** 'が必要です。コンスタンスは途中です。 – aggsol

答えて

3
std::string foo = "foobar"; 
std::vector<char> data(foo.data(), foo.data()+foo.size()+1u); 
char* single[1]; 
single[0] = data.data(); 

How to convert a std::string to const char* or char*?

にあなたの文字列を解析するために、あなたのデータを格納するためにstd::vector<std::string>を使用し、std::stringc_str()を使用することができます。

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

次いで

std::vector<char> lv = literal_vector("Hello"); 
single[0] = lv.data(); 
0

これはもう少しですが、必要なことをするようです。これは、ファイルfoo.cppです:あなたはもちろんdeleteの多分char*の配列の各要素、および機能にstd::stringからchar*にコピーするためのループを置くべき

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

その後
#include <iostream> 
#include <vector> 
#include <string> 
#include <algorithm> 
#include <cstdio> 

int main(int argc, char* argv[]) 
{ 
    std::vector<std::string> 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; 
} 

等々。

PS:このソリューションは、既に誰かがリンクしているthis answerと同じです。リンクされた他の回答には詳細があります。あなたの質問が重複していることを意味しますか?私は経験豊富なユーザーに決定させる。

+0

いいえ私は配列を操作する必要があるので、 'char * val []'または 'char ** val'を必要とします。 – aggsol

+0

@aggsol誤解申し訳ありません。 –

+0

@aggsol私はもっとうまくいったと思います:)少なくとも、すべてのリテラルを書くのは簡単です。そして、あなたは 'new'で作成したメモリにコピーします。これは、 'const'nessをしたい –

-1

このパターンが再発する場合は、あなたが変換関数のいくつかの種類を使用することができますchar*

+0

' c_str() 'は' const char * 'を返さない' char * ' – aggsol

+0

@pergyのように戻すことができます – OrMiz

+0

おそらく危険でUBです。 – Pixelchemist

4

あなたのツールボックスにto_arrayを追加することをお勧めします。次に書くことができます

+0

これは素晴らしい発見です、あまりにもそれはまだ標準ではない悪いです。 – aggsol

1

ここでは、両方ともmemcpyを使用しています。

  1. ダイナミックメモリの使用。
  2. スタティックメモリの使用。


    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; 
    } 

3

あなたの質問は、C++ 1Zとしてタグ付けされていないにもかかわらず、std::stringdata機能のconst性の制限は標準の現在の草案に持ち上げられたことを言及する価値がある(N4618 )、これはC++ 17として公開される予定です。 [基本的な。文字列]、1は両方を見つけることができます。

const charT* data() const noexcept; 
charT* data() noexcept; 

あなたのコンパイラはすでに、おそらくコンパイラフラグ-std=c++1zまたは類似を必要とする、そのためのサポートを有することができます。その場合、次のように書くことができます。

std::string executable = "foobar"; 
char *single[1]; 
single[0] = executable.data(); 
+0

これは私が望む最小限のアプローチであり、まもなく使用される予定です。 – aggsol

関連する問題