2013-10-03 10 views
5

Jest to część zadania domowego. Cóż, nie mogłem sprawić, aby rzeczy działały w mojej pracy domowej, więc wyciągnąłem fragment i zacząłem go używać, aby dowiedzieć się, co jest nie tak.Jak dołączyć do pliku w C, używając trybu Otwórz w O_APPEND na Linux?

Na linux w C Próbuję otworzyć/utworzyć plik tekstowy, napisać coś do niego, zamknij ją, otworzyć go w trybie odczytu/zapisu i tryb dołączyć, a następnie dołączyć nic do końca to (w tym przykładzie ciąg ", koleś"). Nic nie jest jednak dołączane, ale metoda zapisu również nie powoduje błędu. Nie jestem pewien co jest grane.

Oto kod:

#include <stdio.h> 
#include <unistd.h> 
#include <fcntl.h> 
#include <stdlib.h> 
#include <string.h> 
#include <fcntl.h> 
#include <errno.h> 

#define BUFFSIZE 4096 

int main(){ 
    mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; 

    int fd = open("tempfile.txt", O_RDWR | O_CREAT, mode); 

    char buf[BUFFSIZE] = {'t', 'h', 'y', ' ', 'f', 'a', 'l', 'l'}; 

    size_t n = sizeof(buf); 
    if(write (fd, buf, n) < 0){ 
     printf("Error in write\n"); 
     printf("%s", strerror(errno)); 
     return 1; 
    } 

    close(fd); 

    int fd2 = open("tempfile.txt", O_RDWR | O_APPEND); 

    printf("appending dude:\n"); 
    char buf2[6] = {',', ' ', 'd', 'u', 'd', 'e'}; 
    size_t p = sizeof(buf2); 
    if(write (fd2, buf2, p) < 0){ 
     printf("Error in write\n"); 
     printf("%s", strerror(errno)); 
     return 1; 
    } 

    char buf3[BUFFSIZE]; 
    lseek(fd2, 0, SEEK_SET); 
    if(read (fd2, buf3, BUFFSIZE) < 0){ 
     printf("Error in read\n"); 
     printf("%s", strerror(errno)); 
     return 2; 
    } 
    int i; 
    for (i = 0; i < strlen(buf3); ++i){ 
     printf("%c", buf3[i]); 
    } 
    printf("\n"); 

    close(fd2); 

    return 0; 
} 

Próbowałem wyeliminować możliwość, że był ściśle problem uprawnienia przez brudząc z kilku różnych kombinacjach, zmiana trybu pracy na zmienną S_IRWXU | S_IRWXG | S_IRWXO, przekazując tryb jako trzeci argument w mojej drugiej otwartej instrukcji, otwierając tylko plik w trybie dodawania w drugiej otwartej instrukcji, przekazując tryb uzupełniania jako trzeci argument w drugiej otwartej instrukcji, itp.

Najlepsze Mogę zrobić to otworzyć w RDWR bez trybu APPEND, a następnie napisać bezpośrednio nad istniejącym tekstem ... ale tego nie chcę. Zauważ, że jestem świadomy rzeczy takich jak lseek, ale celem jest użycie trybu dodawania w celu dodania tekstu na końcu pliku. Nie chcę lseek.

Jakieś wskazówki, patrząc na to? Jestem pewien, że jest coś oczywistego, czego po prostu nie rozumiem.

Wielkie dzięki.

Odpowiedz

3

liczba bajtów, które próbujesz napisać nie jest poprawna,

char buf[BUFFSIZE] = {'t', 'h', 'y', ' ', 'f', 'a', 'l', 'l'}; 
size_t n = sizeof(buf); 
if(write (fd, buf, n) < 0){ 

zamiast tego należy zrobić

char buf[BUFFSIZE] = {'t', 'h', 'y', ' ', 'f', 'a', 'l', 'l', '\0'}; 
size_t n = strlen(buf); //use strlen 
if(write (fd, buf, n) < 0){ 

Podobnie zrobić dla innego zapisu i brzmi dobrze. Jeśli nie piszesz '\0' w pliku, aby zakończyć ciąg, nie otrzymasz go, gdy czytasz dane z pliku.

Podczas czytania należy wypróbować, aż cały plik zostanie odczytany, tj. otrzymujesz EOF.

+0

Dzięki! To rozwiązało mój problem i dało mi konkretne wyniki, których szukałem. – Deranger

3

Po prostu wypróbowałem twój program i mam pojęcie o tym, co dzieje się nie tak.

Zasadniczo działa, ale z usterką. Kiedy po raz pierwszy napiszesz "twoją jesień" do pliku, użyjesz tablicy z 4096 bajtów i zapiszesz całą tablicę do pliku. Oznacza to, że piszesz "twoją jesień", a następnie 4088 znaków losowych nic. Później, gdy dodasz, dołączasz na 4097. pozycji. Prawdopodobnie nie jest to zamierzone.

Jeśli po prostu cat utworzony plik, zobaczysz oczekiwany wynik "twoja jesień, koleś". Ale kiedy czytasz go w całości w swoim kodzie, czytasz tylko znaki 4096. Dlatego część ", dude" nigdy nie jest czytana, dlatego Twój program nigdy jej nie wyprowadza.

Moje rozwiązanie, musisz zmienić swój rozmiar tablicy. I podczas czytania przeczytaj fragmenty powiedzmy 100 lub 1000, aż trafisz EOF (read zwróci -1).

+0

Słodki. Czy możesz przypadkiem dodać przykład jak używać kota? (Jestem trochę nowy w C, więc nie jestem zaznajomiony, ale sprawdzę go ...) – Deranger

+1

'cat' to polecenie dostępne na dowolnej powłoce linuksa. Jeśli używasz basha, po prostu otwórz terminal, przejdź do katalogu, w którym znajduje się twój program, i wykonaj "cat tempfile.txt". – Nikhil

+0

W porządku - teraz to działa. Myślę, że zarówno ty, jak i Rohan zgadzacie się z tym, co mówisz, ale dodawajcie znaki zerowe, aby zakończyć tablicę i używać strlen zamiast sizeof, jak sugeruje Rohan, dając mi dokładne wyniki, których szukałem. Tak więc zamierzam upowszechniać obie te odpowiedzi, ale wybieram Rohana jako odpowiedź na mój problem. Bardzo dziękuję za Twoją pomoc! – Deranger

1

Jest tylko mały błąd, trzeba zmienić funkcję sizeof do strlen ponieważ funkcja sizeof zwróci rozmiar tablicy ale funkcja strlen prostu wrócić długość łańcucha przechowywane w tablicy!

-1

dlaczego nie wystarczy użyć fopen("text.txt", "a+");

otwiera plik do zapisu i dołączy.