Operacja na plikach C

0

Witam, możecie mi pomóc przy procedurze do edycji wybranego rekordu przez użytkownika? Nie wiem czy to ma być wykonane przez fseek/fwrite lub może jakiś tymczasowy plik binarny.

 

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

using namespace std;

struct SILNIK {
    char oznaczenie[8];
    float pojemnosc;
    float spalanie;
};
struct SAMOCHOD{
    char marka[32];
    char model[32];
    int rocznik;
    SILNIK silnik;
};

void lista_opcji()
{
    puts("===== MENU =======");
    puts("1 - Utworz wpis");
    puts("2 - Wyswietl wpisy");
    puts("3 - Usun wybrany wpis");
    puts("4 - Edytuj wybrany wpis");
    puts("5 - Wyszukaj wybrany wpis");
    puts("6 - Wyszukaj wybrany wpis po marce samochodu");
    puts("7 - Raport do txt");
    puts("8 - Wyczysc ekran");
    puts("9 - Koniec");
    puts("==================");
}

void pobierz_dane(SAMOCHOD* samochod)
{
	printf("podaj marke: ");
	scanf("%s", samochod->marka);
	printf("podaj model: ");
	scanf("%s", samochod->model);
	printf("podaj rocznik: ");
	scanf("%i", &samochod->rocznik);
	printf("podaj oznaczenie silnika: ");
	scanf("%s", samochod->silnik.oznaczenie);
	printf("podaj pojemnosc silnika: ");
	scanf("%f", &samochod->silnik.pojemnosc);
	printf("podaj spalanie silnika: ");
	scanf("%f", &samochod->silnik.spalanie);
}

void dodaj_wpis(SAMOCHOD* samochod, const char* sciezka)
{
    FILE* plik = fopen(sciezka, "ab");
    if (plik == NULL) printf("Plik nie zostal otworzony");
    else
    {
        fwrite(samochod,sizeof(SAMOCHOD),1,plik); //?
        fclose(plik);
    }
}

void wyswietl_wpis(const SAMOCHOD* samochod)
{
	printf(
		"marka:\t\t%s\n"
		"model:\t\t%s\n"
		"rocznik:\t%i\n"
		"silnik:\t\t%s\n"
		"pojemnosc:\t%.2f\n"
		"spalanie:\t%.2f\n",
		samochod->marka,
		samochod->model,
		samochod->rocznik,
		samochod->silnik.oznaczenie,
		samochod->silnik.pojemnosc,
		samochod->silnik.spalanie); //t-tabulacja,f-float, s-char
}

void wyswietl_wpisy (const char *sciezka){
    FILE *plik = fopen(sciezka, "rb");
    int i = 1;
    SAMOCHOD s;
    if (plik)
    {
        while(fread(&s, sizeof(SAMOCHOD), 1, plik))
        {
            printf("===== Wpis %i =====\n", i++);
            wyswietl_wpis(&s);
        }
        fclose(plik);
    }
}

void usun_wpis(const char *sciezka1, const char *sciezka2)
{
    FILE *plik1 = fopen(sciezka1, "rb");
    FILE *plik2 = fopen(sciezka2, "wb");
    SAMOCHOD s;
    int i = 1;
    int index;

    if (plik1 == NULL || plik2 == NULL) printf("ERROR\n");
    else
    {
        printf("Ktory wpis chcesz usunac?\n");
        scanf("%d", &index);
        while(fread(&s, sizeof(SAMOCHOD),1 , plik1)) //1 oznacza maksymalną liczbe elementów,która może zostać wczytana
        {
            if (i++ != index) fwrite(&s, sizeof(SAMOCHOD),1 , plik2);
        }
        fclose(plik1);
        fclose(plik2);
    }
    remove(sciezka1);
    rename(sciezka2, sciezka1);

}

void edytuj_wpis(SAMOCHOD *samochod, const char *sciezka)
{
    FILE *plik = fopen(sciezka, "wb");
    SAMOCHOD s;
    int i = 1;
    int index;

    if (plik == NULL) printf("ERROR\n");
    else
    {
        printf("Ktory wpis chcesz edytowac?");
        scanf("%d", &index);
        fseek(plik, index * sizeof(SAMOCHOD), SEEK_SET);
        pobierz_dane(&s);
        fwrite(samochod, sizeof(SAMOCHOD), 1, plik);
    }
    fclose(plik);
}

int main()
{
    SAMOCHOD s;
    int menu;
    lista_opcji();
    do{
    scanf("%d", &menu);
    switch(menu)
    {
        case 1: pobierz_dane(&s); dodaj_wpis(&s, "baza.dat");break;
        case 2: wyswietl_wpisy("baza.dat");break;
        case 3: usun_wpis("baza.dat", "tmp.dat");break;
        case 4: edytuj_wpis(&s, "baza.dat"); break;
        case 8: system ("cls");lista_opcji();
        case 9: exit;break;
    }
    }while(menu != 9);
    return 0;
}
3

Do edycji otwierasz plik w trybie "rb+" z tego co pamietam. i wtedy fseek na pozycję i zapisujesz writem.

0

Teraz chyba dobrze mi działa edycja. Jeszcze jedno mam pytanie w procedurze pobierz_dane

scanf("%s", samochod->marka); 

chodzi mi o znak ->, co on dokładnie znaczy i dlatego nie może być np. zamiast tego samochod.marka?

 
void edytuj_wpis(SAMOCHOD *samochod, const char *sciezka)
{
    FILE *plik = fopen(sciezka, "r+b");
    SAMOCHOD s;
    int index;

    if (plik == NULL) printf("ERROR\n");
    else
    {
        printf("Ktory wpis chcesz edytowac?\n");
        scanf("%d", &index);
        fseek(plik, (index - 1) * sizeof(SAMOCHOD), SEEK_SET);
        printf("podaj marke: ");
        scanf("%s", s.marka);
        printf("podaj model: ");
        scanf("%s", s.model);
        printf("podaj rocznik: ");
        scanf("%i", &s.rocznik);
        printf("podaj oznaczenie silnika: ");
        scanf("%s", s.silnik.oznaczenie);
        printf("podaj pojemnosc silnika: ");
        scanf("%f", &s.silnik.pojemnosc);
        printf("podaj spalanie silnika: ");
        scanf("%f", &s.silnik.spalanie);
        fwrite(&s, sizeof(SAMOCHOD), 1, plik);
    }
    fclose(plik);
}
0

"->" - odnosisz się do danych przez wskaźnik na obiekt
"." - odnosisz się do danych przez obiekt

3

Ponieważ zmienna samochod jest wskaznikiem i musisz wyłuskać daną spod adresu, możesz to zrobić na 2 sposoby:

samochod->marka

albo

(*samohod).marka

1 użytkowników online, w tym zalogowanych: 0, gości: 1