2

プログラムで生成する約2000行のテキストのファイルがあり、すべての行に従業員の情報があり、次のように出力されます

1 1 ISAAC FONSECA 58 C 1600 1310.40 6 1 0.22 2164.80 1
2 1 Manuel Gutierrez 22 D 1700 1523.37 4 1 0.13 897.26 1
3 1 Daniel Bernal 34 C 1600 1195.84 2 1 0.26 836.16
1 0.00 1

しかし、従業員情報を編集するたびにファイルを更新する必要があり、行を検索して書き直そうとしています。

同じ問題を抱えている人の次の質問を見たことがありますが、ファイルに書き込もうとすると、常にファイルの最後に書き込まれます

テキスト ファイルの特定の行を上書きしますか?

これが私のコードです:

datos = fopen(archivo,"a+");
for(i=0;i<num;i++){
    // buscar la linea
    fgets(lineaA,100,datos);
    // sobreescribir
    if(i == (num-1))
        cursor = ftell(datos);                      
}

cursor -= strlen(lineaA) - 1;
fseek(datos,cursor,SEEK_CUR);

fputs(linea2,datos);            
fclose(datos);
4

3 に答える 3

3

あなたはほとんどこれを行うことはできません.

を使用fseekしてファイル内の特定の場所に移動し、その場所にデータを書き込むことができます (おそらく"r+"モードを使用する必要があります)。

ただし、ファイルは通常、一連の行としてではなく、一連のバイト (または文字) として格納されます。

すでに行にあるのとまったく同じバイト数を注意深く書き込むと、おそらくそれでうまくいく可能性がありますが、この例では行の長さが異なるため、これはオプションではありません。

たとえば、すべて同じ長さになるように各行に空白を埋め込むこともできますが、通常のテキスト エディタなどを使用してファイルを変更すると、レイアウトが崩れやすくなります。

テキスト ファイルの場合、通常の方法は、ファイルをメモリに読み込み、メモリ内の表現を変更してから、ファイル全体を再作成することです。おそらく、内容を新しい一時ファイルに書き込み、書き込みエラーがないことを確認してから名前を変更する必要があります。

これは、テキスト エディタが通常行うことです。

(効率についてはあまり心配しないでください。2000 行はそれほど大きくなく、それらを書くのにかかる時間に気付かないでしょう。)

代替手段があります。固定長レコードでバイナリ形式を定義するか、データベースを使用できます。または、ファイルに新しい行を追加して、重複を削除したかのように扱うこともできます (ただし、これにより、多くの更新を行うとファイルが非常に大きくなる可能性があります)。

于 2012-07-14T22:45:56.880 に答える
1

これが宿題のようなもので、すべてのコードを自分でロールバックする必要がある場合を除き、データベースに切り替えるのがおそらく最も簡単です。残りのコードが機能していることを考えると、おそらくSQLiteが最も明白な選択肢になるでしょう。

あなたが本当に現在のフォーマットとコードに固執したいのであれば (少なくともそれに似たもの)、私はおそらく各行を 64 バイトまたは 128 バイトのようにパディングしてデータを書きます (そして、より長いレコードがいくつかある場合は、分離しますそれらをすべてファイルの末尾に移動するか、別のファイルに入れるなど)。このように (ほとんど?) 編集は、他の行に影響を与えずに行うことができます。従業員の行のインデックスがある場合は、その行を見つけるためにその前の行をすべて読み取る代わりに、その行を直接シークすることもできます。

于 2012-07-14T22:50:11.983 に答える
0

オプション「a +」を使用してファイルを開いています。これは、ファイルに追加することのみを許可し、上書きは許可しません。「r+」を使いたい

datos = fopen(archivo,"r+);
于 2012-07-14T22:44:15.380 に答える