2009-07-29 12 views
6

構造体をファイルに保存したいと思います。 この機能を実現する機能を実現したいと思います。 このコードを試しましたが、動作しませんでした。構造体をファイルに保存するにはどうすればいいですか?C lang

struct utilisateur // enregestrement pour sauvegarder les details de l utilisateur 
{ 
char nom[20]; 
char prenom[20]; 
int place; 
char depart[20]; 
char arrive[20]; 
char sexe; 
int nwagon; 
}; 

struct utilisateur utilis; 
struct utilisateur *Table[48]; 

void crea_fich(struct utilisateur *Tutilis) 
// creation un fichier, vous introduiez le nom, et le sotcker par enreg 
{ 
    FILE *f; 
    if (f!==0) 
    { 
     printf("error in the name of file \n"); 
     exit(1); 
    } 
    if (f=fopen(futilis,"w")==Null){ 
     fprint("We can't creat file \n"); 
     exit(1); 
    } 
    else{ 
     f=fopen("futilis.dat","wb"); 
     fwrite(Tutilis ,sizeof(utilisateur),1,f); 
    } 
} 
+0

問題をフォーマットするだけでなく、テーブルの宣言が奇妙に見えるだけでなく、そのコードスニペットには大きなノイズがあります。あなたの実際のコードがこれまでにあると仮定した場合、fwriteの結果はあなたが期待していたものとどう違うのですか? – brendan

+0

こんにちは。あなたの質問に小さなテキストの書式を付けることができますか?それは読みやすくするでしょう。 – anderstornvig

+0

"if(f!== 0)"で何をしようとしていますか?まず、 "f"は初期化されていないので、その時点でそれを使うのは間違っています。次に、演算子 "!=="はありません。 "!="を使用することを意味します。 –

答えて

0

私は奇妙な\0ことはもちろんのこと、NULLfprintのように、最初のシンボル名の上に見えると思います。もう1つの考えとして、書き込み後にファイルを閉じてディスクにフラッシュするようにして、futilis変数が有効な書き込み可能パスを含むchar*であることを再確認してください。

6

いいえ。データメンバーを1つずつ個別に書き出す必要があります。あなたは盲目的に構造体のメモリ表現をファイル出力バッファにコピーするだけではいけません(あなたがしようとしていることは明らかです)。このようにファイルを書き込むと、構造要素のエンディアンとプラットフォーム固有の埋め込みのため、ファイルを移植不可能にします(書き込まれたプラットフォーム以外では読み込めません)。ただ、簡単な例:)

// your struct 
struct Data 
{ 
    int first; 
    double second; 
    char third[10]; 
}; 

+3

まあ、移植性が必要だとは決して言わなかったので、構造体をファイルシステムに直接書き込むという概念には明白に間違ったものは何もありません。私は1つまたは2つの言語のフロントエンドを知っています。たとえば、解析されたツリーのデータで正確に実行されました。 –

5

は、次に構造体を書きます!

struct Data data = {22, 4.0, "Hi"}; 
FILE* output; 

output = fopen("Data.dat", "wb"); 

fwrite(&data, sizeof(data), 1, output); 

fclose(output); 

最後に、作成したファイルからデータを読み込みます。

struct Data data; 
FILE* input; 

input = fopen("Data.dat", "rb"); 

fread(&data, sizeof(data), 1, input); 

// you got the data from the file! 

fclose(input); 

バイナリファイルは、賢明な記述と読み込みがない限り、悪夢です。ファイルが作成されたアーキテクチャーとそのファイルがどこに読み込まれるかについては、多くのことを考慮する必要があります。エンディアンと変数のサイズが最も重要です。また、structの中にポインタがある場合、ポインタが指す実際のデータではなくファイルに書き込まれるポインタです。申し訳ありませんが、それはコンパイルエラーに満ちているので、私はあなたのコードを編集しませんでした:)

をそれはとても間違っていたので、私は私の最初の答えを削除し、申し訳ありません:)

+0

これはちょっとわかりませんが、ファイルを "r"モードで開いてバイナリデータを書きました( "r"はテキスト、 "rb"はバイナリです)。これはLinuxで違いはありませんが、このコードがWindows、FYIで実行されていると考えられます。 – mox1

+0

申し訳ありません私は良いCの男ではありません:)私はC++を定期的に使用しています。 – AraK

6

はこれを試してみてください、そしてそれが何をしていない場合あなたは、あなたが望むものとどのように違うのか説明しよう。

void crea_fich(struct utilisateur *Tutilis) 
{ 
    FILE *f; 
    size_t nwritten; 

    f = fopen("futilis.dat","wb"); 

    if (f == NULL) 
    { 
     fprintf(stderr, "Cannot open file for writing.\n"); 
     exit(1); 
    } 

    nwritten = fwrite(Tutilis, sizeof Tutilis[0], 1, f); 
    fclose(f); 

    if (nwritten < 1) 
    { 
     fprintf(stderr, "Writing to file failed.\n"); 
     exit(1); 
    } 
} 
+3

これ(と 'fread()'を使用した逆関数)はいずれかのマシンアーキテクチャで動作します。しかし、他のアーキテクチャに移植することはできません。これはおそらく文脈上重要ではありませんが、完全性について言及する価値があります。 –

6

マイケルSは右です。構造体にfwriteを使用すると、大してポータビリティが損なわれます。しかし、あなたがそれを気にしないと思って、簡単に書くことができればいいと思います。型名でsizeofを使用することはありません

あなたのコード内の問題は、あなたがsizeofのゴールデンルールを破ったことです。その代わりに、左辺にsizeofを使用し、ほとんどの場合、別の引数の逆参照のを使用する必要があります。したがって、

このレシピに従うと、サイズを間違って取得するのはずっと難しくなります。

+1

私はそれを「ゴールデンルール」と呼ぶことはほとんどありません。コードのトンと今日については、非左辺値でsizeofを呼び出します。マイクロソフト独自のMSDN Webサイトでは、型名で呼び出す方法を示しています。 http://msdn.microsoft.com/en-us/library/4s7x1k91.aspx – mox1

+0

@James:それは完全に合法です。それは非常に堅牢なプログラミングの練習ではありません。 MSDNがあなたにどのようにあなたを示したかのように、あなたは崖から飛び降りることはありませんか? :-) –

1

私はこれが古い投稿であることを認識していますが、人々がこの情報を検索したときに表示されるので、私自身の解決策を提供します。

これは基本的に私が自分のゲームで使ったものです。私は実際にダイアログのための私の自身の関数でいくつかの特別なライブラリ固有のコードを持っていますが、これは本質的にそれです。私はデータを個別に書きます。私はこのデータのための構造体を持っているとは思わないが、違いはなく、個々の構造体メンバを別々に書くだけです。言及したように、これはこのように優れています。

// returns 1 if successful, 0 if not 
int savemap(const char *map_name) 
{ 
    FILE *file = NULL; 

    // open the file in write binary mode 
    file = fopen(map_name, "wb"); 

    // always check return values to see if it was opened okay 
    if(file == NULL) { 
     fprintf(stderr, "Error opening file for writing.\n"); 
     return 0; 
    } 

    // write file ID, version and pills 
    fwrite(MAP_ID, sizeof(char), strlen(MAP_ID)+1, file); 
    fwrite(&MAP_VER, sizeof(unsigned char), 1, file); 
    fwrite(&pills, sizeof(unsigned short), 1, file); 

    // write the map data (unsigned int map[315]) 
    fwrite(&map, sizeof(unsigned int), 315, file); 

    // never forget to close the file 
    fclose(file); 

    return 1; 
} 
+2

リターンコードは通常0 ==成功、> 0そうでなければ? –

関連する問題