2

ファイルの特定の行を編集する C の問題に直面しています。ファイルの先頭に数字があり、その後にいくつかの行が続きます。なんかこんな感じです。

2
Nasif  20  BUET  130
Oishi  24  KMC  131

実行するたびに、ファイルにもう 1 行追加します。そして、ファイルの最初の数字 (実際には行数を示します) が 1 増えます。このプロセスは機能していないようです。

data=fopen("highscore.txt","r");
fscanf(data,"%d",&number_of_scores);
fclose(data);
if(number_of_scores<10){
    data=fopen("highscore.txt","a");
    fprintf(data,"%s  %s  %s  %s\n", user[current_user].name,
            user[current_user].age, user[current_user].college,result);
    number_of_scores++;
    fseek(data,0,0);
    fprintf(data,"%d",number_of_scores);
    fclose(data);
}
else{

}

では、正しいアプローチとは何でしょうか?

4

4 に答える 4

2

fopen モードについては、http: //www.cplusplus.com/reference/cstdio/fopen/ を参照してください。r+読み取りと書き込みの両方でランダムアクセスの方法でファイルを変更しているため、このオプションを使用する必要があると思います。

"r+" read/update: ファイルを更新用に開きます (入力と出力の両方)。ファイルが存在する必要があります。

"w+" write/update: 空のファイルを作成し、更新用に開きます (入力と出力の両方)。同じ名前のファイルが既に存在する場合、その内容は破棄され、そのファイルは新しい空のファイルとして扱われます。

"a+" 追加/更新: ファイルの末尾にデータを書き込むすべての出力操作で、更新 (入力と出力の両方) のためにファイルを開きます。再配置操作 (fseek、fsetpos、rewind) は次の入力操作に影響しますが、出力操作は位置をファイルの最後に戻します。ファイルが存在しない場合は作成されます。

行数を文字列ではなく符号なし整数としてファイルに保存することをお勧めします。その理由は、文字列として 0 ~ 9 行で 1 バイトが必要になるためです。いずれの場合も、追加の文字が必要な場合は、ファイル全体を書き直す必要があります。これが、スコアの数が 10 未満であることを確認する理由だと思います。

より良い解決策は、ファイルの最初の 4 バイトを符号なし整数として保持し、その後に ASCII テキストを開始することです。

int      result;
uint32_t number_of_scores;
size_t   bytesRead;
FILE     *data;

...

/* Open a file for update (both for input and output).
* The file must exist. */
data = fopen("highscore.txt","r+");
if( !data ) 
    exit(SOME_ERROR_CODE);

/* Read a 32-bit unsigned integer from the file. NOTE there is no endianess
 * "protection" here... ignoring this issue for the sake of simplicity and relevance */
bytesRead = fread (&number_of_scores, sizeof(number_of_scores), 1, data);   
if( bytesRead != 1 )
    exit(SOME_ERROR_CODE);

/* Seek to end of file */
result = fseek(data, 0, SEEK_END);    
if( result )
    exit(SOME_ERROR_CODE);

/* Write in the next line */
result = fprintf(data,
                 "%s  %s  %s  %s\n", 
                 user[current_user].name,
                 user[current_user].age, 
                 user[current_user].college,
                 resultVariableRenamedToAvoidNameCollision);

 /* Up the number of scores and write it back to the start of the file */
 number_of_scores++;
 result = fseek(data, 0, SEEK_SET);      
 if( result )
     exit(SOME_ERROR_CODE);

 bytesRead = fwrite (data, sizeof(number_of_scores), 1, data);
 if( bytesRead != 1 )
    exit(SOME_ERROR_CODE);

 fclose(data);

ああ、私はこの答えがどれほど遅いかを理解しました...気にしないでください:S

于 2013-05-30T16:41:39.633 に答える
0

2 番目の呼び出し で に置き換えてみてください"a"。ファイルの末尾に情報を追加するためのものです。=) "w+"fopen()"a"

編集:ただし、書かれた数字にいくつかの固定スペースを埋め込むこともできます。そうしないと、コードが現在書かれているため、カウントが 9 を超えると、最初の行の行末マーカーが上書きされる可能性があります。

于 2013-05-30T15:49:20.540 に答える