2016-08-11 50 views
0

ファイル内でヒットを見つけようとしていて、書き込みによってそれを変更しようとしています。しかし、Effectue(構造TRAVAILからの)フィールドの変更は適用されません。私は、私は右の(コメント部分が発生)を交換していたことを確認したが、私はまだに設定して最初の出現を得ている関数を呼び出すとき。UNIXファイルの書き込みと書き込み以外の書き込み

TRAVAIL RechercheProchainTravail() { 
    int i, fp; 
    TRAVAIL travailRetour; 

    if ((fp = open("Travaux.dat", O_RDWR | O_CREAT | O_TRUNC, 0664)) == -1) { 
     perror("Err open Travaux.dat"); 
     exit(1); 
    } 

    // init 
    for (i = 0; TravauxInit[i].IndiceLieu > 0; i++) 
     write(fp, &TravauxInit[i], sizeof(TRAVAIL)); 

    // remise au debut 
    lseek(fp, 0, SEEK_SET); 

    //lecture 
    for (i = 0; TravauxInit[i].IndiceLieu > 0; i++) { 
     read(fp, &travailRetour, sizeof(TRAVAIL)); 
     if (travailRetour.Effectue == false) { 
      travailRetour.Effectue = true; 
      lseek(fp, -sizeof(TRAVAIL), SEEK_CUR); 
      /*read(fp, &travailRetour, sizeof(TRAVAIL)); 
      Trace(" indice; %d effect %d", travailRetour.IndiceLieu, travailRetour.Effectue); 
      lseek(fp, -sizeof(TRAVAIL), SEEK_CUR);*/ 
      write(fp, &travailRetour, sizeof(TRAVAIL)); 
      break; 
     } 
    } 
    close(fp); 

    return travailRetour; 
} 

EDIT: ピーターが気づいたように私は切り捨てされてからファイルを防ぐために、オープンを変更しましたが、問題はまだ同じである書き込みがEffectueを変更しないので、私はまだ最初の出現にアクセスフィールド値。

は、ここに私のコードの編集です:

if (access("Travaux.dat", F_OK) != -1) { // si existe ouvrir 
     if ((fp = open("Travaux.dat", O_RDWR, 0664)) == -1) { 
      perror("Err open Travaux.dat"); 
      exit(1); 
     } 
    } else { // sinon creer 
     if ((fp = open("Travaux.dat", O_RDWR | O_CREAT | O_TRUNC, 0664)) == -1) { 
      perror("Err open Travaux.dat"); 
      exit(1); 
     } 
    } 

とリードテストは右の発生を表示するためには、lseek問題ではありません。

+1

現在のコードが示すように、関数を再度呼び出すときにファイル全体を再初期化していませんか? – Peter

+1

'off_t'は署名されており、' size_t'はそうではないので、 '-sizeof(TRAVAIL)'を 'lseek()'の第2引数として渡すことは間違っているか、実装定義です。 – EOF

+0

ああ、確かにピーターが正しいと私は完全にファイルが初期化されるのを忘れてしまった、私はばかげている:p –

答えて

1

この潜在的な問題は間違いなくあります:

lseek(fp, -sizeof(TRAVAIL), SEEK_CUR); 

size_toff_tよりも小さい場合、-sizeof(TRAVAIL)が負の値あなたのように、そしてないようoff_tに変換される大きな符号なしの値(SIZE_MAX - sizeof(TRAVAIL) + 1)であります1つの構造によって後方に追求することを期待する。

あなたはこのようにそれを修正することができます。

lseek(fp, -(off_t)sizeof(TRAVAIL), SEEK_CUR); 

さらに、あなたはreadwritelseekシステムの戻り値をチェックする必要がありますと、すべてが期待どおりに行くことを確認するために呼び出します。

Windows用にコンパイルする場合は、フラグO_BINARYも追加します。

+0

「long」とは関係なく、実装定義されています。 'lseek'は' off_t'をとりますが、必ずしも 'long'であるとは限りません。 – Olaf

+0

@Olaf: 'off_t'に関する良い点ですが、' sizeof(size_t) chqrlie

+0

ええと、私は否定について考えました。しかし、あなたが正しいと思われます。それは、符号なし整数のためによく定義されています。 (でも、私は 'SIZE_MAX'などで議論したいと思います。'sizeof'の代わりに - これはパディングビットの問題を回避します:-) – Olaf

関連する問題