0

私はC言語にかなり慣れておらず、一般的にメモリの割り当て/ポインターの使用を行っています。とにかく、私はファイルの読み取り、それらの値の構造体への配置などを試していました。何をしたいのかは正確にわかっており、もちろんプログラムは実行されますが、出力が正しくなく、数字と文字がごちゃ混ぜになっています。

各行の新しい情報を含むテキスト ファイルがあります。各線は 1 つのオブジェクトを表します。

ファイル内の行は次のようになります。

肉サーロイン 6.55 8 8.50 4

全体として、すべてのオブジェクトを配列に格納できるようにしたいと考えていPRODUCTます (したがって、構造体の配列があります)。そこで、ポインタを使用してメモリを割り当て、行数を使用して、そのポインタを read という関数に送信しようとしました。読み取りでは、ポインターを介して各構造体を配列に追加します。プログラムはクラッシュしません。出力が正しくないだけで、その理由がわかりません。それはおそらくポインタを使ったものです。誰かが私を助けることができれば、本当に感謝しています。どんな助けでも素晴らしいでしょう。

      //prototype
void read(pointerToArr);


typedef struct
{
    char supType[15];
    char prodName[15];
    double wholePrice;
    int quantWhole;
    double retPrice;
    int retProdQuantity;
}PRODUCT;

FILE *fr;
int lineCount = 0;
int main()
{
    PRODUCT *ptr;

    int i;
    char check[50];


     fr = fopen("ttt.txt", "r");

      while(fgets(check, sizeof(check), fr)!= NULL)
      {
          if(check[0] != '\n')
          {
              lineCount++;
          }
      }
    // allocate memory for array based on line count.
     PRODUCT prodContainter[lineCount];
     ptr = (PRODUCT*)malloc(sizeof(PRODUCT)*lineCount);
     ptr = prodContainter;

     read(ptr);

      //print after adding to array via pointer from other
      //function. this was a test.

      for(i = 0; i < lineCount; i++)
      {
          printf("%s ", prodContainter[i].supType);
          printf("%s ", prodContainter[i].prodName);
          printf("%f ", prodContainter[i].wholePrice);
          printf("%d ", prodContainter[i].quantWhole);
          printf("%f ", prodContainter[i].retPrice);
          printf("%d\n\n", prodContainter[i].retProdQuantity);

      }

    return 0;
}



void read(PRODUCT *pointerToArr)
{

    // objective in this method is to read in data from the file, create an object for every line and
    // then use the pointer array to add those objects to prodConstainer up above.

       char supplyName[15];
       char productName[15];
       double wholeP = 0;
       int  quantityWhole = 0;
       double retailPrice = 0;
       int retailProductQuant = 0;

    while(fscanf(fr, "%s %s %lf %d %lf %d", supplyName, productName, &wholeP, &quantityWhole, &retailPrice, &retailProductQuant) == 6)
    {
        PRODUCT record;
        int i;

        strcpy(record.supType, supplyName);
        strcpy(record.prodName, productName);
        record.wholePrice = wholeP;
        record.quantWhole = quantityWhole;
        record.retPrice = retailPrice;
        record.retProdQuantity = retailProductQuant;

        for(i = 0; i < lineCount; i++)
        {
            pointerToArr[i] = record;
        }
    }

    fclose(fr);
}
4

1 に答える 1

2

ファイルを巻き戻すことはないため、行数を数えた後の読み取りはすべて失敗します。

あなたが印刷しているものは、たまたま記憶にあるものです。

もちろん、これを修正する方法はたくさんあります。

  1. を使用して、ファイルを巻き戻します。rewind()
  2. ファイルを閉じて、read()関数 (その名前は POSIX 標準関数と衝突します) でファイルを再度開きます。これには、恐ろしいグローバル変数の削除も含まれますfr
  3. ptr必要に応じて配列を読み取って拡張するだけで、行数をカウントしないように再構築します(「参考文献」を参照realloc())。

また、Cの戻り値をキャストすることは本当に避けるべきですmalloc()。これ:

ptr = (PRODUCT*)malloc(sizeof(PRODUCT)*lineCount);

次のように書く方が良いです:

ptr = malloc(lineCount * sizeof *ptr);

これにより、キャストが不要になり、指定sizeof された型の値を使用して、 割り当てる適切なバイト数が自動的に計算されます。

于 2013-01-31T16:34:31.540 に答える