質問
可能な限り最良の方法で文字列の静的配列のすべての要素を反復しようとしています。1 行で宣言し、番号を追跡することなく要素を簡単に追加/削除できるようにしたいと考えています。とても簡単そうに思えますね。
考えられる解決策以外の解決策:
vector<string> v;
v.push_back("abc");
b.push_back("xyz");
for(int i = 0; i < v.size(); i++)
cout << v[i] << endl;
問題 - 文字列のリストを含むベクトルを 1 行で作成する方法がありません
考えられる非解決策 2:
string list[] = {"abc", "xyz"};
問題 - (私が知っている) 文字列の数を自動的に取得する方法はありません。
これを行う簡単な方法があるはずです。
解決
の ブーストアサインライブラリ まさにあなたが探しているもののようです。これにより、コンテナへの定数の割り当てがこれまでより簡単になります。
他のヒント
C++ 11 では、次の構文を使用できる初期化リストが追加されました。
std::vector<std::string> v = {"Hello", "World"};
この C++ 11 機能のサポートは、少なくとも GCC 4.4 そしてのみ Visual Studio 2013.
簡潔に初期化できます vector<string>
静的に作成されたものから char*
配列:
char* strarray[] = {"hey", "sup", "dogg"};
vector<string> strvector(strarray, strarray + 3);
ちなみに、これはすべての文字列をコピーするので、メモリを 2 倍使用します。Will Dean の提案を使用して、ここでの魔法の数字 3 を arraysize(str_array) に置き換えることができます。ただし、arraysize の特定のバージョンが何か悪いことをする可能性がある特殊なケースがあったことは覚えています (詳細をすぐに思い出せなくて申し訳ありません) 。しかし、多くの場合、正しく動作します。
また、1 行のことに本当にこだわりがある場合は、次のような 1 行を実行するように可変個引数マクロを定義できます。 DEFINE_STR_VEC(strvector, "hi", "there", "everyone");
動作します。
問題 - (私が知っている) 文字列の数を自動的に取得する方法はありません。
これを行うには標準的な方法があり、多くの人 (MS を含む) が次のようなマクロを定義しています。 arraysize
のために:
#define arraysize(ar) (sizeof(ar) / sizeof(ar[0]))
C++ で文字列の配列を次のように宣言します。 char array_of_strings[][]
例えば : char array_of_strings[200][8192];
200 個の文字列が保持され、各文字列のサイズは 8kb または 8192 バイトになります。
使用 strcpy(line[i],tempBuffer);
データを文字列の配列に配置します。
1 つの可能性は、フラグ値として NULL ポインターを使用することです。
const char *list[] = {"dog", "cat", NULL};
for (char **iList = list; *iList != NULL; ++iList)
{
cout << *iList;
}
使用できます begin
そして end
Boost range ライブラリの関数を使用すると、プリミティブ配列の終端を簡単に見つけることができます。マクロ ソリューションとは異なり、これを誤ってポインターに適用すると、壊れた動作ではなくコンパイル エラーが発生します。
const char* array[] = { "cat", "dog", "horse" };
vector<string> vec(begin(array), end(array));
Will Dean の提案を使用できます [
#define arraysize(ar) (sizeof(ar) / sizeof(ar[0]))
] ここでマジックナンバー 3 を arraysize(str_array) に置き換えます -- ただし、arraysize の特定のバージョンが何か悪いことをする可能性がある特殊なケースがあったことは覚えています (詳細をすぐに思い出せなくて申し訳ありません)。しかし、多くの場合、正しく動作します。
これが機能しないケースは、「配列」が実際には単なるポインタであり、実際の配列ではない場合です。また、配列が関数に渡される方法 (最初の要素へのポインターに変換される) のため、シグネチャが配列のように見えても、複数の関数呼び出しにわたって機能しません。 some_function(string parameter[])
本当に some_function(string *parameter)
.
boost::assign を使用する必要があるという Craig H の回答に賛成票を投じようとしましたが、担当者がいません:(
私が初めて読んだ Andrei Alexandrescu の記事で同様の手法に遭遇しました。 C/C++ ユーザー ジャーナル, 、第16巻、第9号、1998年9月、pp.73-74 (それ以来ずっと使用している彼のコードの実装のコメントにあるので、完全な引用を持っています)。
テンプレートはあなたの友達です。
以下に例を示します。
#include <iostream>
#include <string>
#include <vector>
#include <iterator>
int main() {
const char* const list[] = {"zip", "zam", "bam"};
const size_t len = sizeof(list) / sizeof(list[0]);
for (size_t i = 0; i < len; ++i)
std::cout << list[i] << "\n";
const std::vector<string> v(list, list + len);
std::copy(v.begin(), v.end(), std::ostream_iterator<string>(std::cout, "\n"));
}
そのマクロの代わりに、これを提案できますか?
template<typename T, int N>
inline size_t array_size(T(&)[N])
{
return N;
}
#define ARRAY_SIZE(X) (sizeof(array_size(X)) ? (sizeof(X) / sizeof((X)[0])) : -1)
1) マクロを使用してコンパイル時の定数にしたいと考えています。関数呼び出しの結果はコンパイル時の定数ではありません。
2) ただし、マクロは誤ってポインターで使用される可能性があるため、マクロは使用しません。この関数はコンパイル時の配列でのみ使用できます。
そこで、関数の定義性を利用してマクロを「安全」にします。関数が存在する場合 (つまり、サイズがゼロではない場合)、上記のようにマクロを使用します。関数が存在しない場合は、不正な値が返されます。
#include <boost/foreach.hpp>
const char* list[] = {"abc", "xyz"};
BOOST_FOREACH(const char* str, list)
{
cout << str << endl;
}
#include <iostream>
#include <string>
#include <vector>
#include <boost/assign/list_of.hpp>
int main()
{
const std::vector< std::string > v = boost::assign::list_of( "abc" )( "xyz" );
std::copy(
v.begin(),
v.end(),
std::ostream_iterator< std::string >( std::cout, "\n" ) );
}
#include <iostream.h>
#include <iomanip.h>
int main()
{
int n;
cout<<"enter the maximum number\n";
cin>>n;
cout<<"enter the first number\n";
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
cin>>a[i][j];
}
}
cout<<"enter the second number\n";
for(int i=0;i<n;i++)
{
for(int k=0;k<n;k++)
{
cin>>b[i][k];
}
}
cout<<"the product will be\n";
for(int i=0;i<n;i++)
{
for(int g=0;g<n;g++)
{
c[i][g]=c[i][c]*c[i][j];
cout<<setw(5)<<c[i][g];
}
cout<<endl;
}
return 0;
}
次のような文字列の配列を直接宣言できます。 string s[100];
。次に、特定の要素にアクセスしたい場合は、次のように直接取得できます s[2][90]
. 。反復の目的で、次を使用して文字列のサイズを取得します。s[i].size()
関数。