文書番号: 38728
最終更新日: 2003/01/16
この資料は以下の製品について記述したものです。
- Microsoft C for MS-DOS
- Microsoft C/C++ for MS-DOS
- Microsoft Visual C++ 1.0
- Microsoft Visual C++ 1.5
- Microsoft Visual C++ 1.51
- Microsoft Visual C++ 1.52
- Microsoft Visual C++ 2.0
- Microsoft Visual C++ 2.1
- Microsoft Visual C++ 4.0
- Microsoft Visual C++, 32-bit Enterprise Edition 5.0
- Microsoft Visual C++, 32-bit Enterprise Edition 6.0
- Microsoft Visual C++, 32-bit Professional Edition 5.0
- Microsoft Visual C++, 32-bit Professional Edition 6.0
- Microsoft Visual C++, 32-bit Learning Edition 6.0
この記事は、以前は次の ID で公開されていました: JP38728
概要
C プログラミングにおける一般的な問題として、大きな文字配列の初期化があります。これにはいくつかの方法がありますが、潜在的な問題もいくつか存在します。
方法 1
:
文字列リテラル
文字配列を初期化する 1 つの方法は、文字列リテラルを使用するものです。
ANSI では、連結後の文字列リテラルが最低 509 文字までは処理されることを保証しています。
初期のバージョンの Microsoft C/C++ におけるこの制限は、それぞれのコンパイラのバージョンにより 512 ~ 2048 文字の間になります。文字列リテラルの長さには制限があるため、この方法では制限よりも長い文字配列を初期化することはできません したがって、char a[] = "12"; というステートメントを使用した場合、その文字配列の要素数は 3 になります)。
ほとんどのエディタでは行の長さにも制限があるため、通常はこうした大量の文字を文字列リテラルに直接記述することはできません。ただし、引用符で囲んだ文字列を並べると、コンパイラによって単一の文字列に連結されます。したがって、
char a[] = "a"
"b";
上記の宣言は下記と同じ意味になります。
char a[] = "ab";
この方法を使用すると、大きなリテラルの初期化子は、以下に示すコードに置き換えることができます。この方法では、文字列の長さの上限はコンパイラの仕様によって決まります。s
char stuff[] =
"xxx...xxx"
...
"xxx...xxx";
(ANSI 規格では、空白のみで分割した文字列は自動的に連結されると決められています。)
方法 2 : 文字の初期化子
次のコードを使用できます。
char stuff [] =
{ 'a', ...
...
... 'z' };
ただし、こうした初期化子を入力するには膨大な手間がかかります。この方法を使用する場合は、データ ファイルを読み込んで必要な初期化子を出力するプログラムを記述してください。
方法 3 : 多次元配列
char stuff[][10] = {
"0123456789",
...
"0123456789" };
この 10 という値自体は重要ではありませんが、必ず文字列定数の実際の長さに一致する必要があります。指定された長さよりも短い文字列定数があった場合、その行の残りの部分は 0 (ゼロ) のバイトで埋められます。指定された長さよりも長い文字列の場合は、余分な文字が切り捨てられます。こうして 2 次元配列が得られます。次のように、別のポインタを使用すれば、ほとんどどのようにでもアクセスすることができます。
char *stuffptr = (char *) stuff;
この方法が最も便利なものに思われます。ポインタを使って、1 次元配列として配列にアクセスする方法の大きな問題は、余分な null 文字によってカウントが困難になることです。すべての初期化文字列が同じ長さになっていない場合は特にそうです。したがって、stuffptr[97] と記述しても、非常に注意してカウントしなければ、正しい要素にアクセスできない可能性があります。
方法 4 : アセンブリ モジュール
配列を MASM で定義して C プログラムにリンクすることもできます。MASM では、セグメントと public 定義が正しく行われていれば、次のように記述することができます。
stuff db "abcdefghijkl"
db "morestuff"
...
db "laststuff"
C 側では、この配列に次のようにアクセスします。
extern char stuff[]; /* char * stuff は使用できない */
方法 5 : ファイルから読み込む
もう 1 つの方法は、実行時にデータ ファイルから値を配列に読み込むものです。大きなブロックでファイルの読み込みが行われる場合 (たとえば、read や fread を使用する場合)、I/O は極めて高速になります。また、この方法には、コードを変更して再コンパイルしなくても初期化文字列を変更できるという利点もあります。
関連情報
この資料は米国 Microsoft Corporation から提供されている Knowledge Base の Article ID 38728 (最終更新日 2001-11-14) をもとに作成したものです。
この資料に含まれているサンプル コード/プログラムは英語版を前提に書かれたものをありのままに記述しており、日本語環境での動作は確認されておりません。
Keywords: JPTRF kbhowto kbHOWTOmaster kbLangC kbVC100 kbVC150 kbVC151 kbVC152 kbVC200 kbVC210 kbVC400 kbVC500 kbVC600 KB38728
Technology: kbAudDeveloper kbCCompSearch kbvc100 kbvc150 kbVC151 kbVC152 kbVC200 kbVC210 kbVC32bitSearch kbVC400 kbVC500 kbVC500Search kbVC600 kbVCsearch kbZNotKeyword3 kbZNotKeyword8