How to delete the last line of a text file in the C language

0

Well, I'm wondering how I should delete the last line of a file using the C language. Could anyone help me please.

Below, follow my code.

int quantidadeDeUsuarios = 0;
Usuario *_usuario;



void sair() {
    free(_usuario);
}

void removerUltimoNumero() {

    FILE *arquivo;

    char *linha = (char *) malloc(256 * sizeof(char));
    char *buffer = (char *) malloc(1000 * sizeof(char));
    char *ponteiro;

    memset(buffer, 0, 1000 * sizeof(char));
    ponteiro = buffer;

    arquivo = fopen("usuarios", "r");

    if(arquivo == NULL) {
        cout << "Erro na abertura do arquivo" << endl;
        return;
    }

    while(!feof(arquivo)) {

        fgets(linha, 256, arquivo);

        if(sizeof(linha) == true) {
            strcpy(ponteiro, linha);
            ponteiro += strlen(linha);
        }
    }

    fclose(arquivo);
    rescreveArquivo(arquivo, buffer);
    free(linha);
    free(buffer);
}

void rescreveArquivo(FILE *arquivo, const char *buffer) {
    arquivo = fopen("usuarios", "w");
    fprintf(arquivo, "%s", buffer);
    fclose(arquivo);
}

void numeroDeUsuariosCadastrados() {
    cout << "Número de usuários cadastrados: " << contadorDeLinhasDeUmArquivo() << endl;
}

int contadorDeLinhasDeUmArquivo() {

    FILE *arquivo;
    int numeroDeLinhas = 0;

    arquivo = fopen("usuarios", "r");

    if(arquivo == NULL) {
        cout << "Erro na abertura do arquivo" << endl;
        return 0;
    }

    while(EOF != (scanf("%*[^\n]") && scanf("%*c"))) {
        ++numeroDeLinhas;
    }

    return numeroDeLinhas;
}

void listarUsuarios() {

    char *saida = (char *) malloc(256 * sizeof(char));
    char espaco = ' ';

    FILE *arquivo = fopen("usuarios", "r");

    if(arquivo == NULL) {
        cout << "Erro na Abertura do arquivo" << endl;
        return;
    }

    cout << "=========================================================================================================================================================" << endl;
    printf("| Nome %-25c | RG %-27c | CPF %-26c | Endereço %-41c |\n", espaco, espaco, espaco, espaco);
    cout << "=========================================================================================================================================================" << endl;

    for (int i = 1; fgets(saida, sizeof(saida), arquivo) != NULL; ++i) {
        printf("%s", saida);
    }

    cout << endl << endl;

    fclose(arquivo);

}

void cadastrarUsuario() {

    Usuario *usuario;

    usuario = _usuario;

    if(quantidadeDeUsuarios > 0) usuario = (Usuario *) realloc(usuario, quantidadeDeUsuarios * sizeof(Usuario));
    else usuario = (Usuario *) malloc(sizeof(Usuario));

    if(!usuario) {
        cout << "Exaustão de memória!" << endl;
        exit(1);
    }

    __fpurge(stdin);
    cin.clear();
    cout << "Digite seu nome: ";
    cin.getline(usuario[quantidadeDeUsuarios].nome, 100);

    __fpurge(stdin);
    cin.clear();
    cout << "Digite seu RG: ";
    cin.getline(usuario[quantidadeDeUsuarios].rg, 9);

    __fpurge(stdin);
    cin.clear();
    cout << "Digite seu CPF: ";
    cin.getline(usuario[quantidadeDeUsuarios].cpf, 11);

    __fpurge(stdin);
    cin.clear();
    cout << "Digite seu Endereço: ";
    cin.getline(usuario[quantidadeDeUsuarios].endereco, 100);

    _usuario = usuario;

    insereUsuario(_usuario);

    quantidadeDeUsuarios++;

}

void insereUsuario(Usuario *pUsuario) {

    FILE * arquivo;

    if((arquivo = fopen("usuarios", "a+")) == NULL) {
        cout << "Erro ao criar o arquivo";
    }

    fprintf(arquivo, "| %-30s | %-30s | %-30s | %-50s |\n",
            pUsuario->nome,
            pUsuario->rg,
            pUsuario->cpf,
            pUsuario->endereco
    );

    fclose(arquivo);

}
    
asked by anonymous 25.02.2017 / 21:10

2 answers

0

I was able to solve the problem by taking the data from a text file to a dynamic allocation. Then I handled the location pointer by typing the data into the same file.

void removerUltimoUsuario() {

FILE *arquivo = fopen("usuarios.csv", "r");

if(arquivo == NULL) {
    cout << "Erro ao criar o arquivo" << endl;
}

Usuario *usuarios = (Usuario *) malloc(numeroDeUsuarios() * sizeof(Usuario));

char linha[500];
int i = 0;
for(; fgets(linha, 500, arquivo); i++) {
    linha[strlen(linha) - 1] = '
void removerUltimoUsuario() {

FILE *arquivo = fopen("usuarios.csv", "r");

if(arquivo == NULL) {
    cout << "Erro ao criar o arquivo" << endl;
}

Usuario *usuarios = (Usuario *) malloc(numeroDeUsuarios() * sizeof(Usuario));

char linha[500];
int i = 0;
for(; fgets(linha, 500, arquivo); i++) {
    linha[strlen(linha) - 1] = '%pre%';
    sscanf(linha, "%[^;];%[^;];%[^;];%[^;];",
           usuarios[i].nome,
           usuarios[i].rg,
           usuarios[i].cpf,
           usuarios[i].endereco
    );
}
cout << "N: " << i << endl;
fclose(arquivo);
insereUsuarios(usuarios, i);
free(usuarios);

cout << "Usuário removido com sucesso!" << endl;
}




void insereUsuarios(Usuario *pUsuario, int numUsuarios) {

FILE * arquivo;

if((arquivo = fopen("usuarios.csv", "w")) == NULL) {
    cout << "Erro ao criar o arquivo";
}

cout << "N: " << numUsuarios << endl;

for(int i = 0; i < (numUsuarios-1); i++) {
    fprintf(arquivo, "%s;%s;%s;%s\n",
            pUsuario[i].nome,
            pUsuario[i].rg,
            pUsuario[i].cpf,
            pUsuario[i].endereco
    );
}

fclose(arquivo);
}
'; sscanf(linha, "%[^;];%[^;];%[^;];%[^;];", usuarios[i].nome, usuarios[i].rg, usuarios[i].cpf, usuarios[i].endereco ); } cout << "N: " << i << endl; fclose(arquivo); insereUsuarios(usuarios, i); free(usuarios); cout << "Usuário removido com sucesso!" << endl; } void insereUsuarios(Usuario *pUsuario, int numUsuarios) { FILE * arquivo; if((arquivo = fopen("usuarios.csv", "w")) == NULL) { cout << "Erro ao criar o arquivo"; } cout << "N: " << numUsuarios << endl; for(int i = 0; i < (numUsuarios-1); i++) { fprintf(arquivo, "%s;%s;%s;%s\n", pUsuario[i].nome, pUsuario[i].rg, pUsuario[i].cpf, pUsuario[i].endereco ); } fclose(arquivo); }
    
06.03.2017 / 05:05
0

It has a very simple way using its function that already counts the number of lines of the file. But first, I want to make it clear that I have not reviewed or tested your code. I'm just going to leave a theoretical solution for you to implement. Let's go .

  • First create an output file.
  • Now having the output file created and the number of lines in the original file, copy line by line from the original file to the output file.
  • When you get to the last line (which you want to delete) just skip it, that is, do not copy it to the output file.
  • You now have 2 files, the original and the output. Rename or delete the original file and keep the output file as the "new original".
  • I do not think this is the most recommended solution. But as far as I've read your code, this is the best way to have less impact on your implementation.

    NOTE: Be sure to treat all errors during this process. This will ensure that your output file is as complete as you expect.

        
    03.03.2017 / 03:23