0

私はCプログラミングに非常に慣れていないので、おそらく非常に単純な問題があります。

私はこのような構造体を手に入れました

typedef struct Vector{
    int a;
    int b;
    int c;
}Vector;

ここで、ベクトルの配列をファイルに書き込みたいと思います。それを実現するために、次のメソッドスキームを作成しようと思いました

String createVectorString(Vector vec){
    // (1)
}

String createVectorArrayString(Vector arr[]){
    int i;
    String arrayString;
    for(i=0; i<sizeof(arr); i++){
        //append createVectorString(arr[i]) to arrayString  (2)
    }
}

void writeInFile(Vector arr[]){
    FILE *file;
    file = fopen("sorted_vectors.txt", "a+");
    fprintf(file, "%s", createVectorArrayString(arr);
    fclose(file);
}

int main(void){

    // create here my array of Vectors (this has already been made and is not part of the question)
    // then call writeInFile

    return 0;
}

私の主な問題は(1)にあり、これには(2)も含まれます(Cで文字列を操作する方法がわからないため、Eclipseは「Type "String" unknown」と言っていますが、これを含めました<string.h>

だから私はある時点でintをStringに変換することがメソッドitoa()で可能であることを読みました。私が理解したように、私は簡単に次のことを行うことができます

char buf[33];
int a = 5;
itoa(a, buf, 10)

ただし、それを機能させることはできません。ましてや、 charsまたはintsを文字列に「貼り付ける」方法がわからないことは言うまでもありません。

私のポイント(1)では、フォームの文字列を作成したいと思います(a,b,c)。ここで、a、b、およびcは、構造体ベクトルの「フィールド」です。

ポイント(2)で、フォームの単一の文字列を作成したいと思います(a1,b1,c1)\n(a2,b2,c2)\n...(an,bn,cn)。ここで、nは配列内のベクトルの量です。

迅速な解決策はありますか?Javaの文字列の概念とCの文字列の概念を混同しませんか?

4

4 に答える 4

4

はい、JavaとCの文字列の概念を混同しています。

C文字列は操作がかなり不便です。それらは動的メモリ割り当てを必要とし、さらに悪いことに、対応する割り当て解除(これは可能ですが退屈です)を必要とします。あなたの場合、文字列を完全に削除し、文字列なしで必要なものを実装するのが最善かもしれません。

ベクトルをファイルに直接書き込むには:

Vector vec;
FILE* file = ...;
fprintf(file, "%d %d %\n", vec.a, vec.b, vec.c);

ベクトルの配列を作成するには、上記をループで実行します。

于 2012-10-18T20:02:26.740 に答える
2

Cの文字列は、nullで終了する文字の配列です。通常はとして宣言されchar *ますが、最大長が固定されていて、スタックまたは構造体のインラインに割り当てることができる場合は、として宣言される可能性がありますchar str[LENGTH]

文字と数字の組み合わせから文字列を作成する最も簡単な方法の1つは、を使用することsnprintf()です。これはに似printf()ていますが、標準出力に出力する代わりに、文字列(の配列char)に出力します。自分でバッファを割り当てて渡す必要があることに注意してください。したがって、事前に最大長を知る必要があります。または、を呼び出してsnprintf()、印刷される文字数を調べ、そのサイズの配列を割り当ててから、snprintf()もう一度呼び出して実際に結果を印刷することで確認する必要があります。

したがって、3つの整数のベクトルがあり、それから文字列を作成する場合は、次のように記述できます。

char *createVectorString(Vector vec){
    int count = snprintf(NULL, 0, "(%d,%d,%d)", vec.a, vec.b, vec.c);
    if (count < 0)
        return NULL;
    char *result = malloc(count * sizeof(char));
    if (result == NULL)
        return NULL;
    count = snprintf(result, count, "(%d,%d,%d)", vec.a, vec.b, vec.c);
    if (count < 0)
        return NULL;
    return result;
}

malloc()このバッファを割り当てるために呼び出しfree()たので、メモリリークを回避するために、それが終わったら呼び出す必要があることに注意してください。

snprintf()C99の時点で必要な長さのみを返すことに注意してください。一部のコンパイラ(MSVCなど)はまだC99をサポートしていないため、文字列の長さではなく-1を返します。そのような場合、必要なバッファーのサイズを決定するために呼び出すことができる別の関数があるかもしれません(MSVCではそれ_vscprintfです)、またはサイズを推測する必要があるかもしれません、そしてそれがうまくいかない場合は、バッファーを割り当てますそのサイズの2倍にして、成功するまで再試行します。

于 2012-10-18T20:14:47.757 に答える
1

はい、 Java文字列とC混同しています。

  1. Cで配列を渡すことはできず、最初の要素へのポインタのみを渡すことができます。
  2. sizeof (arr)ここで、arrは関数の引数であり、ポインターのサイズです。
  3. ブロックスコープの文字列を返すことはできません。文字列へのポインタのみを返すことができます。ただし、関数が戻ると、ローカル自動変数へのポインターはスコープ外になります。

もっとループを書きます

#define N 42

/* Typedef for Vector assumed somewhere.*/
Vector arr[N];
/* Fill arr[]. */

for (i = 0; i < N; ++i) {
    fprintf (file, "arr[%d] =  { a=%d, b=%d, c=%d }\n", i, arr[i].a, arr[i].b, arr[i].c);
}
于 2012-10-18T20:06:16.640 に答える
1

つまり、はい、Java文字列とCを混同しています。ここでは、標準の文字列型がありません。文字列とは、実際には、値0(または、純粋になりたい場合は'\ 0')のcharで終了する一連のcharです。

最も手っ取り早い解決策は、文字列を生成しない(そしてすべてのメモリを手動で割り当てる)のではなく、で使用fprintfすることFILE*です。FILE*文字列を作成する関数の代わりに、たとえば、提供されたものにさまざまなものを書き込む関数を記述しますint writeVector(FILE* output, Vector v)。最初は簡単になります。このような文字列を作成するために必要な手動メモリ管理の厄介な詳細のすべてが良いスタートだとは思いません。

(提案されたプロトタイプのintの戻りタイプに注意してください。これはエラーコード用です。)

さらに、コメント投稿者の1人が指摘したように、sizeofを誤解しています。sizeof(arr)結合された配列のすべての要素のサイズをバイト単位で返します(技術的には文字単位ですが、今は気にする必要のない違いです)。配列内の要素の数を取得するには、を使用する必要がありますsizeof(arr)/sizeof(arr[0])。しかし、構文が凝っていても、技術的にはポインタである関数の引数で機能するかどうかはわかりません。sizeofをポインターに適用すると、ポインターが指すデータではなく、ポインター自体のサイズが返されます。

そのため、Cでは通常、次のような追加の関数引数で配列のサイズを指定します。

String createVectorArrayString(Vector arr[], size_t n)

私が上で書いたことに沿って以上:

int writeVectorArray(FILE *output, Vector arr[], size_t n)
{
  int retcode = 0;
  size_t i;
  for (i = 0; i < n; ++i) {
    if ( (retcode = writeVector(output, arr[i])) != 0)
      return retcode;
  }
}
于 2012-10-18T20:04:26.770 に答える