Jak skasować zawartość pliku, poprawa złych nawyków

0

Nie wiem jak skasować zawartość pliku tekstowego po jego przeczytaniu. Czy można ustawić jakiś odpowiedni argument w funkcji fopen ? Nie mogłem też znaleźć funkcji która by kasowała zawartość. Mile widziane są też podpowiedzi odnośnie stylu pisania ponieważ nie chciał bym się uczyć złych nawyków, jeżeli coś się da zrobić lepiej ( pewnie wszystko ) to proszę o podpowiedź.

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

#include "p1.h"

#define BUFSIZE 8000
#define INIT_BODY_SIZE 10


void fatal(int err, const char *msg){
    if (!err) return;
    fprintf(stderr, "%s\n", msg);
    exit(EXIT_FAILURE);
}

struct body * init_body(int initial_size){
    struct body * ns = malloc( sizeof *ns );
    fatal( ns == NULL, "Za mało pamięci");
    ns->t = malloc( initial_size * sizeof * ns->t );
    fatal( ns->t == NULL, "Za mało pamięci");
    ns->size = initial_size;
    ns->n = 0;
    return ns;
}

struct body * resize_body(struct body *ns){
    char **np = realloc( ns->t, 2 * ns->size * sizeof *ns->t );
    fatal( np == NULL, "Za mało pamięci" );
    ns->size *=2;
    ns->t = np;
    return ns;
}

void add_body(char * mt, struct body * ms) {
    if ( ms->n == ms->size ) ms = resize_body(ms);
    ms->t[ms->n] = malloc( ( strlen(mt) + 1 ) * sizeof *ms->t);
    fatal(ms->t[ms->n] == NULL, "Za mało pamięci");
    strcpy(ms->t[ms->n], mt);
    ms->n++;
    return;
}

void print_body(struct body *ms, FILE *out){
    int i;
    for ( i = 0; i < ms->n; i++ )
        fprintf( out, "%s", ms->t[i]);
}
     
int main (int argc, char ** argv) {

    char buf[BUFSIZE];
    FILE *in = argc > 1 ? fopen(argv[1], "r+") : NULL;
    FILE *out = argc > 2 ? fopen(argv[2], "w") : in;
    struct body *mystruct = init_body(INIT_BODY_SIZE);
    char * search = "//";

    fatal( !in, "Podaj plik z którego mam czytać");
    fatal( !out, "Podaj plik do którego mam pisać");
    while ( fgets( buf, BUFSIZE, in) != NULL ){
        char *ws = strstr(buf, search);
        int lastchar = strlen(buf);
        if (ws != NULL) {
            *(ws+1) = '*';
            buf[lastchar - 1] = '*';
            buf[lastchar ] = '/';
            buf[lastchar + 1] = '\n';
            buf[lastchar + 2] = '\0';
        }
        add_body(buf, mystruct);
    }
    print_body(mystruct, out);
    return EXIT_SUCCESS;
}
1

a nie lepiej skasowac plik i utworzyc go na nowo?

1

fopen z parametrem "w" usuwa plik jeżeli istnieje.
Z tym że w twoim kodzie oba pliki otwierają się jednocześnie na początku, więc to się nie udaje ponieważ plik już jest otwarty do odczytu.

0

Mam jeszcze pytanie czy prawidłowo zwalniam pamięć ?

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

#include "p1.h"

#define BUFSIZE 8000
#define INIT_BODY_SIZE 10


void fatal(int err, const char *msg){
    if (!err) return;
    fprintf(stderr, "%s\n", msg);
    exit(EXIT_FAILURE);
}

struct body * init_body(int initial_size){
    struct body * ns = malloc( sizeof *ns );
    fatal( ns == NULL, "Za mało pamięci");
    ns->t = malloc( initial_size * sizeof * ns->t );
    fatal( ns->t == NULL, "Za mało pamięci");
    ns->size = initial_size;
    ns->n = 0;
    return ns;
}

struct body * resize_body(struct body *ns){
    char **np = realloc( ns->t, 2 * ns->size * sizeof *ns->t );
    fatal( np == NULL, "Za mało pamięci" );
    ns->size *=2;
    ns->t = np;
    return ns;
}

void add_body(char * mt, struct body * ms) {
    if ( ms->n == ms->size ) ms = resize_body(ms);
    ms->t[ms->n] = malloc( ( strlen(mt) + 1 ) * sizeof *ms->t);
    fatal(ms->t[ms->n] == NULL, "Za mało pamięci");
    strcpy(ms->t[ms->n], mt);
    ms->n++;
    return;
}

void print_body(struct body *ms, FILE *out){
    int i;
    for ( i = 0; i < ms->n; i++ )
        fprintf( out, "%s", ms->t[i]);
}

void free_body(struct body *ms){
    int i;
    for ( i = 0; i < ms->n; i++)
        free(ms->t[i]);
    free(ms);
} 
     
int main (int argc, char ** argv) {
     int i;

    for (i = 1; i < argc; i++){
        char buf[BUFSIZE];
        FILE *in = fopen(argv[i], "r");
        struct body *mystruct = init_body(INIT_BODY_SIZE);
        char * search = "//";


        fatal( !in, "Jeden z plików które podałeś ma błędna nazwę lub nie masz uprawnień do jego odczytu");
        while ( fgets( buf, BUFSIZE, in) != NULL ){
            char *ws = strstr(buf, search);
            int lastchar = strlen(buf);
            if (ws != NULL) {
                *(ws+1) = '*';
                buf[lastchar - 1] = '*';
                buf[lastchar ] = '/';
                buf[lastchar + 1] = '\n';
                buf[lastchar + 2] = '\0';
            }
            add_body(buf, mystruct);
        }
        fclose(in);
        fatal( remove(argv[i]), "Nie mogę usunąć pliku przed ponownym zapisem" );
        in = fopen(argv[i], "w");
        fatal( !in, "Nie mogę otworzyć pliku do pisania" );
        print_body(mystruct, in);
        free_body(mystruct);
    }
    return EXIT_SUCCESS;
}
1

Nie.

0

Jak powinno być poprawnie?

1

Masz zwolnić wszystko co przydzielałeś:

  1. struct body * ns = malloc( sizeof *ns );
  2. ns->t = malloc( initial_size * sizeof * ns->t );
  3. ms->t[ms->n] = malloc( ( strlen(mt) + 1 ) * sizeof *ms->t);

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