0

実行時に利用できるいくつかのドキュメントを含む小さなライブラリがありますが、MS Visual Studio C++ コンパイラでは最大2,048 バイトの長さの文字列リテラルしか許可されていません。この制限を回避する簡単な方法はありますか? 私が見つけた唯一の解決策は、文字列配列を作成し、新しいバッファを割り当てて文字列をコピーすることでした。

char *doc_arr[] = {
    "Documentation for my program\n",
    "\n",
    "This is a seccond line\n",
    // and so on ....
}
int doc_arr_length = 203; // number lines in doc_arr
char doc[3502];           // number of bytes in dockumentation

strcpy(doc, doc_arr[0]);
for(int i = 1; i < doc_arr_length; i++){
    strcat(doc, doc_arr[i]);
}

更新: いくつかのコンテキストが必要なようです。

多くのオプションを取り、多くのデータを収集して .c ファイルを生成する ruby​​ プログラムがあります。.c ファイルは .dll ウィッチにコンパイルされ、高速計算のために他のプログラムで使用されます。これは、さまざまな .c および .dll がすぐに取得され、バージョンの管理が難しくなることを意味します。ソースファイルとコンパイルされた dll に ruby​​ スクリプトに与えられたオプションに関する合成ドキュメントを含めることをお勧めします。

4

4 に答える 4

7

より良い(IMO)代替手段で質問に答える:

ドキュメントを別のファイルで配布します。実行時にファイルを開き、必要なものを読み取ります。

外部ドキュメントはコード内に存在しません。

于 2012-06-07T07:45:20.543 に答える
2

Windowsでアプリケーションを構築している場合、文字列リテラルの場所はリソースファイルにあります。管理がはるかに簡単で、翻訳をサポートしています。

文字列を直接埋め込むことはお勧めできません。

于 2012-06-07T07:50:37.237 に答える
0

これはあなたの質問に対する答えではありません。他の人はすでにそれに答えています。ただし、コメントはコードを投稿するのに適していません。

コードは次のようなコードに修正する必要があります (コンパイルもテストもされていません)。

const char *doc_arr[] = {
    "Documentation for my program\n",
    "\n",
    "This is a seccond line\n",
    // and so on ....
};
int doc_arr_length = 203; // number lines in doc_arr
char doc[3502];           // number of bytes in dockumentation

const char* doc_ptr = doc;

for(int i = 0; i < doc_arr_length; i++){
    int length = strlen(doc_arr[i]);
    memcpy(doc_ptr, 
           doc_arr[i], 
           sizeof(char)*length + 1);
    doc_ptr += length;
}

修正された問題:

  • 文字列リテラルを扱うときは常に const ポインターを使用してください。ポインターを介して文字列リテラルを意図的または非意図的に変更すると、未定義の動作が発生しました。
  • ループ条件が正しくなく、ループが奇妙でした。

最適化:

  • このようなループで strcat を繰り返し呼び出すと、非常に非効率的になります。ループの反復ごとに、strcat() は、null 終端を探して、着実に成長する文字列を通過する必要があります。ポインターを介して最後の位置を追跡することにより、プログラムはループ内のすべてのラップでこの遅いルックアップを実行する必要がなくなります。
  • 上記のポインターを導入する場合、コピーする文字列の文字列の長さを知る必要があります。strlen() を呼び出してこの情報を利用できるようにしたので、null 終端を検索する strcat() や strcpy() などの「遅い」関数を呼び出す必要はありません。代わりに strncpy() または memcpy() を使用できます。この場合、strncpy() の追加機能 (追加の null 終端の追加) は役に立たないため、memcpy() を選択しました。
于 2012-06-07T08:39:40.357 に答える
0

他の人が示唆しているように、別のファイルを使用する方がおそらく簡単ですが、展開に関しては複雑さが増します. 別の方法として、私がよく行うのは、文字列のテーブルを使用して、各行を個別のエントリに入れることです。

char const* doc[] =
{
    "first line",
    "next line",
    //  ...
    "last line",
};

出力するには、次のようにします。

std::copy( begin(doc), end(doc),
           std::ostream_iterator<std::string>( std::cout, "\n" ) );

これはうまく機能しているようで、視覚的な書式設定が可能です。またはその他:vimでは、ブロックをマークして実行し:s/ *"\(.*\)",/\1/(マークされたブロックで標準的な検索と置換のみ)、適切なツールを使用してフォーマットします。エディターの内部コマンド(かなり単純)を使用するか、いくつかの外部コマンド (必要に応じて複雑にすることができます) にパイプし、最後に:s/.*/ "&",/C++ 句読点を復元します。

于 2012-06-07T08:03:56.673 に答える