2011-04-03 23 views
12

"a + b" modunu kullanarak bir dosya açmak istiyorum, yani eğer mevcut değilse otomatik olarak oluşturulur, ancak eğer bunun üzerine yazmak istemiyorum. Dosyayı okuyabilmek ve yazabilmek istiyorum.fseek(), dosya tanıtıcısı "a + b" modunda açılmışsa dosyanın başlangıcına gider mi?

Dosya ikili ve içine belirli bir struct kayıtlarını kaydetmek istiyorum. Bu yüzden istediğim rekoru fseek() yapmak ve daha sonra kayıt fwrite() kullanarak kaydetmek istiyorum. Ancak bu kod sadece dosyanın sonuna kayıt ekler

int saveRecord(MyRecord *pRecord, int pos) 
{ 
    FILE* file = fopen(FILENAME, "a+b"); 
    if (file == NULL) 
    { 
     printf("Unable to open file %s\n", FILENAME); 
     return 0; 
    } 

    fseek(file, pos * sizeof(MyRecord), SEEK_SET); 
    fwrite(pRecord, sizeof(MyRecord), 1, file); 
    fclose(file); 
    return 1; 
} 

, şu şekildedir: (FILENAME dosya adının yanındaki bir #define iken, MyRecord bir struct bir typedef olan)

kod görünüyor pos değerini 0 olarak ayarlasaydım bile neden SEEK_SET ek modda çalışıyor?

"r + b" ile açabileceğimi ve "wb" ile açılmayı başarabileceğimi biliyorum, ancak bunun neden çalışmadığını ve neden ile dosya tanıtıcısını bıraktığını bilmek istiyorum son. Bu davranışın belgelendiği yerlere yapılan göndermeler takdir edildi (çünkü bulamadım veya yanlış anahtar kelimeleri kullanıyorum).

cevap

18

Bu, a kipinde, FILE*'a yazma işleminin her zaman sonuna kadar eklenmesidir. fseek sadece okuma işaretçisini bu modda ayarlar. Bu 7.19.5.3 fopen, C standardında belgelenmiştir:

zorlanacak için dosyanın sonraki tüm yazma neden Ekleme modunda (mod argümanı ilk karakter olarak 'a') ile bir dosya açma fseek işlevine yapılan çağrılara bakılmaksızın o anda geçerli dosya sonu, .

+0

Teşekkürler, ihtiyacım olan cevap. – jbx

4

"r + b" modunu kullanın ve başarısız olursa "w + b" için geri dönüş yapın.

"a + b" modu, okumanızı ve eklemenizi sağlar; "r + b", rastgele okuma ve yazma sağlar.

fopen belgeleri, dosyanın farklı modlarla nasıl davrandığını açıklar.

+0

Bu dosyanın bilmeden edecek bir yarış durumu var. –

+0

@R ..: Hangi yarış koşulları? "errno == ENOENT" ile başarısız olursa "wp back to" diyorum " – pmg

+0

" Bir başka işlemin dosyayı oluşturabildiği ve ilk "fopen" den sonra verilerle doldurabildiği çoklu görev işletim sistemi varsayıyorum ama önce ikinci fopen denemesi. OP, gömülü bir sistemle veya bunun gerçekleşmeyeceği bilinen herhangi bir kapalı sistemle uğraşırsa, sorun olmayabilir. –

4

Düz C, istediğiniz şeyi elde etmek için herhangi bir akıl yolu yoktur. Bir POSIX sisteminde veya uzaktan yakın bir konumdaysanız, fd=open(FILENAME, O_CREAT|O_RDRW, 0666) ve ardından fdopen(fd, "rb+")'u kullanabilirsiniz.

Düzenleme: düz C, deneyebilirsiniz başka şey:

f = fopen(FILENAME, "a+b"); 
if (!f) /* ... */ 
tmp = freopen(0, "r+b", f); 
if (tmp) f = tmp; 
else /* ... */ 
+0

Evet, sanırım işe yarayacaktı. Saf ANSI C üzerinde çalışmak için buna ihtiyacım var. İyi bir alternatif için hala +1. – jbx

+0

'freopen' çözümünü denediniz mi? Pratikte işe yarayıp yaramadığına dair bir fikir yok ('freopen' kötü tanımlanmış ve teoride işe yaramaz olabilir) ama iyi olabilir. –