0

C++でギザギザの二次元配列を作りたいです。

int arrsize[3] = {10, 5, 2};
char** record;
record = (char**)malloc(3);
cout << endl << sizeof(record) << endl;
for (int i = 0; i < 3; i++) 
{
    record[i] = (char *)malloc(arrsize[i] * sizeof(char *));
    cout << endl << sizeof(record[i]) << endl;
}

record[0]名前(10文字が必要)、record[1]マーク(5桁のマークが必要)、およびrecord[3]ID(2桁の数字が必要)に設定したい。どうすればこれを実装できますか? レコード配列をバイナリ ファイルに直接書き込みます。と を使いたくありませstructclass

4

4 に答える 4

5

C++ では、次のようになります。

std::vector<std::string> record;
于 2011-11-03T06:47:52.537 に答える
2

問題の賢明な解決策であるのに、なぜ構造体を使用しないのでしょうか?

struct record {
   char name[10];
   char mark[5];
   char id[2];
};

次に、バイナリ ファイルへの書き込みは簡単になります。

record r = get_a_record();
write( fd, &r, sizeof r );

ノート:

  • NUL ターミネータに少し余分なスペースを割り当てたい場合もありますが、これはファイルで使用する形式によって異なります。

  • markバイナリ ファイルに書き込んでいる場合、なぜid文字列として書きたいのでしょうか。int(4 バイト、より広い範囲の値) とunsigned char(1 バイト)を保存しない理由

ユーザー定義型を使用しないことを主張する場合 (実際には使用する必要があります)、単一のメモリ ブロックを作成してポインター演算を使用できますが、コンパイラによって生成されるバイナリは同じになることに注意してください。唯一の違いは次のとおりです。コードの保守性が低下します。

char record[ 10+5+2 ];
// copy name to record
// copy mark to record+10
// copy id to record+15
write( fd, record, sizeof record);
于 2011-11-03T08:48:04.310 に答える
0

実際、「malloc する」正しいパターンは次のとおりです。

T * p = (T *) malloc(count * sizeof(T));

whereTは、 を含む任意のタイプである可能性がありますchar *。したがって、この場合にメモリを割り当てるための正しいコードは次のようになります。

int arrsize[3] = { 10, 5, 2 };
char** record;
record = (char**) malloc(3 * sizeof(char *));
cout << sizeof(record) << endl;
for (int i = 0; i < 3; ++i) {
    record[i] = (char *) malloc(arrsize[i] * sizeof(char));
}

cout'ing を削除sizeof(record[i])したのは、char への (1) ポインターのサイズ (私のラップトップでは 4) が常に生成されるためです。sizeof はコンパイル時に再生されるものであり、実行時に割り当てられたrecord[i](実際にはポインター型である) が指すメモリの量はわかりません。char *

于 2011-11-03T07:07:06.917 に答える
0

malloc(3)3 バイトを割り当てます。ジャグ配列は、文字配列へのポインターを含む配列になります。各ポインタは通常 4 バイト (32 ビット マシン上) を使用しますが、より正確sizeof(char*)には を使用して割り当てる必要がありますmalloc(3 * sizeof(char*) )

そしてrecord[i] = (char*)malloc((arrsize[i]+1) * sizeof(char))、文字列は achar*であり、文字はcharであり、各 C スタイルの文字列は慣習'\0'的にその長さを示す文字で終了するためです。なくてもできますが、たとえば次のように使用するのは難しくなります。

strcpy(record[0], name);
sprintf(record[1], "%0.2f", mark);
sprintf(record[2], "%d", id);

sprintf最後に a を入れるので、あなたの記録を記入してください\0mark浮動小数点数でありid、整数であると想定しました。

これらすべてをファイルに書き込むことに関して、ファイルがバイナリの場合、最初にすべてを文字列として入れるのはなぜですか? あなたがそうすると仮定すると、次のようなものを使用できます:

ofstream f("myfile",ios_base::out|ios_base::binary);
for (int i=0; i<3; i++)
    f.write(record[i], arrsize[i]);
f.close();

そうは言っても、私はアンダースの考えを支持します。STL のベクトルと文字列を使用すると、面倒なメモリ割り当てに対処する必要がなくなり、コードもきれいに見えるでしょう。

于 2011-11-03T07:08:19.607 に答える