1

まだCは初めてですが、コツをつかみ始めています。

私のプログラムは、ファイルを作成/書き込みし、構造体の配列から情報を格納することになっています。その部分は大丈夫です。問題を抱えているのは、そのファイルから構造体の空の配列に読み戻すことです。

これが私の構造体です:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#define MAX 100

struct Video { 
char name[1024];                //name
int ranking;                // Number of viewer hits
char url[1024];             // YouTube URL
};

struct Video Collection[MAX];

これが私のファイルから構造体の配列に読み戻す私のloadメソッドです:

void load()
{
FILE *fileName;
fileName = fopen("ranking.dbm", "rb");
if (fileName != NULL){
    fread (Collection,1,1,fileName);
}
else {
    printf("ERROR");
}   

}

また、ここに私の書き込みメソッドがあります:

void save()
{
FILE * pFile;
pFile = fopen ( "Ranking.dbm" , "wb" );
fwrite (Collection, 1 , sizeof(Collection), pFile );
fclose (pFile); 
}

ただし、ロード後に配列を印刷するとcollection....空です...プロジェクトフォルダ内のファイルを確認して開き、データがそこにあることを確認できますが...。

使用する前にバッファを処理する必要がないので、バッファは必要ないと考えるのは正しいですか?

また、メモリ用のスペースをすでに静的に割り当てているので、配列に直接読み取ることができると考えるのは正しいですか?

これが私の印刷コードです:

void printall()
{
int i; 

printf("\nCollections: \n"); 

for(i = 0; i < tail; i++)
{
    printf("\nVideo Name: %s", Collection[i].name);
    printf("\nRanking (Hits): %d", Collection[i].ranking);
    printf("\nURL: %s", Collection[i].url);
    printf("\n");
}
}
4

3 に答える 3

4

fread実際には、ファイルから構造体の配列を読み取るように設計されていますが、正しく使用する必要があります。

freadの4つのパラメータは次のとおりです。

void * ptr, size_t size, size_t count, FILE * stream

最初のパラメーターは、データを配置する場所です(あなたの場合はCollection)。2番目のパラメーターは、各配列要素のサイズです。この場合、を配置しsizeof(struct Video)ます。3番目のパラメーターは、読み取りたい要素の数です。この場合は、MAXです。4番目のパラメーターは、読み取るファイルです。

のような配列に読み込みたい場合struct Video Collection[MAX]は、を使用しますfread(Collection, sizeof(struct Video), MAX, file)fread読み取られた要素の総数を返します。これは≤MAXです。

于 2012-09-29T18:26:33.913 に答える
2

ここにいくつかの問題があります。最初にファイルを読み取る方法:

fread (Collection,1,1,fileName); 

これにより、コレクションに1バイトが読み込まれfileNameますCollection
。の戻りステータスを確認する必要がfread()あります。成功すると、読み込まれるバイトの総数が示されます。(パラメーター2 *パラメーター3、またはあなたの場合は1 * 1)。

読み取りコードを次のように変更すると、次のようになります。

fread(Collection, sizeof(struct Video), 1, fileName);

ファイルから正常に読み取られます...ただし、現在は別の問題があります。あなたのファイルがこれを含んでいたとしましょう:

something 5 http://something.com
nothing 3 http://nothing.com

つまり、(私は)それがファイルの形式、名前(ASCII)、ランキング(int)、およびURL(ASCII)です。main()ここで、関数が次のようになっているとしましょう。

int main ()
{
    load();
    printall();
    return 0;
}

あなたが取り戻すstdoutものは次のようなものになるでしょう:

Collections:

Video Name: something 6 http://something.com
nothing 3 http://nothing.com
Ranking (Hits): 0
URL: 

その理由は、静的な(そして非常に大きな)要素を使用して配列を宣言したためです。は1024+4 + 1024バイトのデータfread()を読み込もうとするsizeof(struct Video)ため、すべての行が正確なサイズ(名前とURLに1024文字)でない限り、データがめちゃくちゃになったり空になったりするように見えます。 。

ファイル全体を配列に読み出そうとするのではなく、スペースに入るまで読み、各値を正しい要素に格納することをお勧めします。

編集:
次のようにアレイにデータを入力する場合:

fread(myarray, sizeofstruct, numberofstructs, file);

データ長を保証する必要があります。あなたの例では、「名前は何文字でも、+空白スペース= 1024」と言う必要があり、URLについても同じです。それは恐ろしいスペースの浪費のようです。より良い方法は、配列に一度に1つの要素を設定することです。

for(0 to last_element){
  set myarray.name = data until first space
  set myarray.ranking = (int)data until second space
  set myarray.url = data until newline
}

fscanf()空白まで読むために使用できます。率直に言って、一度に1つの要素を設定する場合は、名前とURLに文字ポインターを使用し、動的にメモリを割り当てるだけなので、大量の無駄な配列が発生することはありません。

于 2012-09-29T19:27:04.470 に答える
1

最初に私はあなたがstruct Video Collection[MAX];そうでなければあなたの上部が無効なCであることを意味したと仮定しなければなりません。

2番目:コレクションに1バイトを読み込んでいます。

試す fread(Collection, sizeof(struct Video), MAX, fileName);

MAXこれにより、最大で数倍のsizeof(struct Video)バイトがコレクションに読み込まれます。

于 2012-09-29T18:26:23.587 に答える