Thread: fprintf doesn't write to file anymore

  1. #1
    Registered User
    Join Date
    Apr 2015
    Posts
    180

    fprintf doesn't write to file anymore

    I'am building a program that creates files with input from user using structs. I'am having problem with doing that right.
    I don't understand what the problem is, it was working fine sometime ago then i decided to try new things and all of a sudden it stopped working. Right now i'am just focusing on function Adicionar(), it should printf to the file the data that the user gives.



    Code:
    #include <stdio.h>#include <stdlib.h>
    #include <string.h>
    
    
    void Menu(FILE *f);
    
    
    typedef struct
    {
        int numTeste;
        float nota;
        char descricao[50]; 
        
    }Aluno;
    
    
    void Listar(FILE *f)
    {
    
    
    }
    
    
    void Adicionar(FILE *f)
    {
        int N;
        printf("Quantos testes deseja inserir?");
        scanf("%d", &N);
        Aluno novoAluno[N];
        for(int i=0;i<N;i++)
        {
            printf("Insira o numero do teste: ");
            scanf("%d", &novoAluno[i].numTeste);
            printf("%d", novoAluno[i].numTeste);
            fprintf(f, "%d\n", novoAluno[i].numTeste);
            printf("Insira a nota: ");
            scanf("%f", &novoAluno[i].nota);
            printf("%.2f", novoAluno[i].nota);
            fprintf(f, "%.2f\n", novoAluno[i].nota);
            printf("Insira detalhes(pratica, teoria...): ");
            scanf("%s", novoAluno[i].descricao);
            fprintf(f, "%s\n", novoAluno[i].descricao);
        }
        printf("\n");
        printf("Todos os dados relativos aos testes foram inseridos.\n");
        printf("****************************************************\n");
        Menu(f);
        
        
    }
    
    
    void Editar()
    {
        
        
    }
    
    
    void Remover()
    {
        
    }
    
    
    void Menu(FILE *f)
    {
        int opcao;
        
        printf("   Menu\n\n");
        printf("1 --> Listar\n");
        printf("2 --> Adicionar\n");
        printf("3 --> Editar\n");
        printf("4 --> Remover\n");
        printf("5 --> Sair\n");
        scanf(" %d", &opcao);
            
        switch(opcao)
        {
            case 1: Listar(f);break;
            case 2: Adicionar(f);break;
            case 3: Editar();break;
            case 4: Remover();break;
            case 5: printf("A fechar o programa!\n"); break;
            default : printf("Opcao invalida!\n"); break;
                
        }    
            
    
    
    }
    
    
    
    
    
    
    int main()
    {
        
        
        char nomeFicheiro[50];
        printf("Qual o nome do ficheiro a criar? ");
        scanf("%s", nomeFicheiro);
        char auxFicheiro[50];
        sprintf(auxFicheiro, "%s.txt", nomeFicheiro);
        FILE *f;
        f=fopen(auxFicheiro, "w+");
        if(f==NULL)
        {
            printf("Erro\n");
            return 0;
        }    
        Menu(f);
        
    }
    Last edited by telmo_d; 05-08-2015 at 09:18 AM.

  2. #2
    Registered User
    Join Date
    Jun 2011
    Posts
    4,513
    What exactly is the problem you're seeing?

    Code:
    for(int i=0;i<N;N++)
    Are you sure that "N" is the value you want to be incrementing here?

  3. #3
    Registered User
    Join Date
    Apr 2015
    Posts
    180
    Ups that's wrong, fixed that. My problem is that fprintf is not printing anything to file. The program is creating the file with the name the users wants but then it doesnt write anything to it. Which is weird since it was doing that just fine some time ago and i don't see much difference in the code.

  4. #4
    Registered User
    Join Date
    Jun 2011
    Posts
    4,513
    Seems to work fine for me:

    Code:
    Qual o nome do ficheiro a criar? telmo
       Menu
    
    1 --> Listar
    2 --> Adicionar
    3 --> Editar
    4 --> Remover
    5 --> Sair
    2
    Quantos testes deseja inserir?1
    Insira o numero do teste: 2
    2Insira a nota: 3.0
    3.00Insira detalhes(pratica, teoria...): hello
    
    Todos os dados relativos aos testes foram inseridos.
    ****************************************************
       Menu
    
    1 --> Listar
    2 --> Adicionar
    3 --> Editar
    4 --> Remover
    5 --> Sair
    5
    A fechar o programa!
    Code:
    // telmo.txt
    
    2
    3.00
    hello
    I also did a test case with 6 additions, which also worked.

    Are the values printing to the screen as expected? Are you entering "5" as the menu choice when you're done with menu choice 2? If so, are the exit prompts occurring as expected?

    I also suggest you put the "menu()" call into a loop in "main()". As it is, you are approaching a strange sort of recursion, where "menu()" calls a function, that function calls "menu()" at the end, and so on.

  5. #5
    Registered User
    Join Date
    Apr 2015
    Posts
    180
    Funny i wasn't doing the 5 to quit and that was the problem, now it works fine. I was just doing ctrl+c but i think before it worked with that but i'am not sure.
    How do you suggest i do loop in main with Menu()? One doubt do i need return 0 in Adiciionar() or it's useless since it's a void function?

  6. #6
    Registered User
    Join Date
    Jun 2011
    Posts
    4,513
    Funny i wasn't doing the 5 to quit and that was the problem, now it works fine. I was just doing ctrl+c but i think before it worked with that but i'am not sure.
    Then it's likely the output stream to the file was not being flushed in the current version of your code (but possibly was in the previous version). To test, flush the output in your loop, terminate the program with ctrl+c, and see if it works that time.

    Code:
    fflush(f);
    However, you should let the program end naturally. This way, the file will be closed (which causes the output to be flushed) and everything should work without explicitly flushing it.

    How do you suggest i do loop in main with Menu()?
    Well, a good function should do one thing, and do it well. With that in mind, your "menu()" function is doing more than it should.

    One approach might be as follows:

    • Modify the "menu()" function so that it prints the menu, reads the input, and returns the input to "main()"
    • In "main()", store the return value of "menu()" into a variable
    • Use this returned value to determine what to do next (call another function, change the value of a flag, etc)
    • Put the above two things into a loop, and use [an already mentioned] flag to determine whether to continue looping or not.


    One doubt do i need return 0 in Adiciionar() or it's useless since it's a void function?
    Returning zero would be wrong, since as you said, the function is declared with return type void.

    Note, however, it is legal to return (with no value) from a void function. You normally do not need to explicitly return from a void function, but this can come in handy if you need to break out of a void function early.

    Here's a contrived example:

    Code:
    void print_int_division(int dividend, int divisor)
    {
        /* We cannot divide by zero, so exit the
           function  if "divisor" is zero */
        if(divisor == 0)
            return;  // void function, so we return, but do NOT return a value
    
        printf("%d / %d = %d\n",dividend,divisor,dividend/divisor);
    }
    Last edited by Matticus; 05-08-2015 at 05:21 PM.

  7. #7
    Registered User
    Join Date
    Apr 2015
    Posts
    180
    Like this is good? I'am now working on Listar() function that has to printf the file to the screen. I think it's having problems reading from the file since the program is crashing when it calls this function. Why is this? Initially i had w+ which i didn't know erased he file if it exists so i changed to r+ but it's still crashing.

    Code:
    #include <stdio.h>#include <stdlib.h>
    #include <string.h>
    
    
    int Menu(FILE *f);
    
    
    typedef struct
    {
    	int numTeste;
    	float nota;
    	char descricao[50]; 
    	
    }Aluno;
    
    
    void Listar(FILE *f)
    {
    	int N;
    	Aluno novoAluno[N];
    	char st[10];
    	N=0;
    	while(fgets(st, 10, f)!=NULL)
    	{
    		novoAluno[N].numTeste=atoi(st);
    		fgets(st, 10, f);
    		novoAluno[N].nota=atof(st);
    		fgets(novoAluno[N].descricao, 50, f);
    		N++;
    	}
    	printf("Existem %d testes\n\n", N);
    	int i;
    	for(i=0;i<N;i++)
    	{
    		printf("Teste %d\n", novoAluno[i].numTeste);
    		printf("Nota:  %.2f\n", novoAluno[i].nota);
    		printf("Descricao: %s\n", novoAluno[i].descricao);
    	}
    	
    }
    
    
    void Adicionar(FILE *f)
    {
    	int N;
    	printf("Quantos testes deseja inserir?");
    	scanf("%d", &N);
    	Aluno novoAluno[N];
    	for(int i=0;i<N;i++)
    	{
    		printf("Insira o numero do teste: ");
    		scanf("%d", &novoAluno[i].numTeste);
    		printf("%d", novoAluno[i].numTeste);
    		fprintf(f, "%d\n", novoAluno[i].numTeste);
    		printf("Insira a nota: ");
    		scanf("%f", &novoAluno[i].nota);
    		printf("%.2f", novoAluno[i].nota);
    		fprintf(f, "%.2f\n", novoAluno[i].nota);
    		printf("Insira detalhes(pratica, teoria...): ");
    		scanf("%s", novoAluno[i].descricao);
    		fprintf(f, "%s\n", novoAluno[i].descricao);
    	}
    	fseek(f, 0, SEEK_SET);
    	printf("\n");
    	printf("Todos os dados relativos aos testes foram inseridos.\n");
    	printf("****************************************************\n");
    	
    	
    	
    	
    }
    
    
    void Editar()
    {
    	
    	
    }
    
    
    void Remover()
    {
    	
    }
    
    
    int Menu(FILE *f)
    {
    	int opcao;
    	
    	printf("   Menu\n\n");
    	printf("1 --> Listar\n");
    	printf("2 --> Adicionar\n");
    	printf("3 --> Editar\n");
    	printf("4 --> Remover\n");
    	printf("5 --> Sair\n");
    	scanf("%d", &opcao);
    		
    	switch(opcao)
    	{
    		case 1: Listar(f);break;
    		case 2: Adicionar(f); break;
    		case 3: Editar();break;
    		case 4: Remover();break;
    		case 5: printf("A fechar o programa!\n"); break;
    		default : printf("Opcao invalida!\n"); break;
    			
    	}
    	return opcao;	
    }
    
    
    int main()
    {
    	char nomeFicheiro[50];
    	printf("Qual o nome do ficheiro a criar? ");
    	scanf("%s", nomeFicheiro);
    	char auxFicheiro[50];
    	sprintf(auxFicheiro, "%s.txt", nomeFicheiro);
    	FILE *f;
    	f=fopen(auxFicheiro, "r+");
    	if(f==NULL)
    	{
    		printf("Erro\n");
    		return 0;
    	}	
    	int valorMenu;
    	do
    	{
    		valorMenu=Menu(f);
    	}while((valorMenu>=1)&&(valorMenu<=4));
    	
    	
    	
    	return 0;
    }
    Last edited by telmo_d; 05-09-2015 at 03:28 AM.

  8. #8
    Registered User
    Join Date
    Apr 2015
    Posts
    180
    Just realized what the problem was, i forgot to set the file position to the start of the file. With rewind(f) or fseek it works.
    Last edited by telmo_d; 05-09-2015 at 03:29 AM.

  9. #9
    Registered User
    Join Date
    Apr 2015
    Posts
    180
    Now working on function Editar() which is supposed to edit data on the file. I'am having troubles with fseek. Say i have a file with struct below, it has integer, then float, then char[50]. To make it write in next line shouldn't i write
    Code:
    fseek(f, (sizeof(novoAluno[0].numTeste)+sizeof(novoAluno[0].nota)+sizeof(novoAluno[0].descricao)), SEEK_SET);
    I tried something like that in the code but it has crazy behaviour now.

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    
    int Menu(FILE *f);
    
    
    typedef struct
    {
        int numTeste;
        float nota;
        char descricao[50]; 
        
    }Aluno;
    
    
    void Listar(FILE *f)
    {
        int N;
        Aluno novoAluno[N];
        char st[10];
        N=0;
        while(fgets(st, 10, f)!=NULL)
        {
            novoAluno[N].numTeste=atoi(st);
            fgets(st, 10, f);
            novoAluno[N].nota=atof(st);
            fgets(novoAluno[N].descricao, 50, f);
            N++;
        }
        printf("Existem %d testes\n\n", N);
        int i;
        for(i=0;i<N;i++)
        {
            printf("Teste %d\n", novoAluno[i].numTeste);
            printf("Nota:  %.2f\n", novoAluno[i].nota);
            printf("Descricao: %s\n", novoAluno[i].descricao);
        }
        fseek(f, 0, SEEK_SET);
        
    }
    
    
    void Adicionar(FILE *f)
    {
        int N;
        printf("Quantos testes deseja inserir?");
        scanf("%d", &N);
        Aluno novoAluno[N];
        for(int i=0;i<N;i++)
        {
            printf("Insira o numero do teste: ");
            scanf("%d", &novoAluno[i].numTeste);
            //printf("%d", novoAluno[i].numTeste);
            fprintf(f, "%d\n", novoAluno[i].numTeste);
            printf("Insira a nota: ");
            scanf("%f", &novoAluno[i].nota);
            //printf("%.2f", novoAluno[i].nota);
            fprintf(f, "%.2f\n", novoAluno[i].nota);
            printf("Insira detalhes(pratica, teoria...): ");
            scanf("%s", novoAluno[i].descricao);
            fprintf(f, "%s\n", novoAluno[i].descricao);
        }
        fseek(f, 0, SEEK_SET);
        printf("\n");
        printf("Todos os dados relativos aos testes foram inseridos.\n");
        printf("****************************************************\n");
        
        
        
        
    }
    
    
    void Editar(FILE *f)
    {
        int N, K;
        char st[10];
        Aluno novoAluno[N];
        printf("Qual o teste que deseja editar? ");
        scanf("%d", &K);
        N=0;
        while(fgets(st, 10, f)!=NULL)
        {
            novoAluno[N].numTeste=atoi(st);
            fgets(st, 10, f);
            novoAluno[N].nota=atof(st);
            fgets(novoAluno[N].descricao, 50, f);
            N++;
        }
        printf("Existem %d testes\n\n", N);
        if(K==1)
        {
            fseek(f, 0, SEEK_SET);
        }
        else if(K>1)
        {
            fseek(f, K*(sizeof(novoAluno[0].numTeste)+sizeof(novoAluno[0].numTeste)+sizeof(novoAluno[0].nota)+sizeof(novoAluno[0].descricao)), SEEK_SET);
        }
        printf("Introduza a nota: ");
        scanf("%f", &novoAluno[K-1].nota);
        fprintf(f, "%.2f", novoAluno[K-1].nota);
        printf("Teorica ou Pratica? ");
        scanf("%s", novoAluno[K-1].descricao);
        fprintf(f, "%s", novoAluno[K-1].descricao);
    }
    
    
    void Remover()
    {
        
    }
    
    
    int Menu(FILE *f)
    {
        int opcao;
        
        printf("   Menu\n\n");
        printf("1 --> Listar\n");
        printf("2 --> Adicionar\n");
        printf("3 --> Editar\n");
        printf("4 --> Remover\n");
        printf("5 --> Sair\n");
        scanf("%d", &opcao);
            
        switch(opcao)
        {
            case 1: Listar(f);break;
            case 2: Adicionar(f); break;
            case 3: Editar(f);break;
            case 4: Remover();break;
            case 5: printf("A fechar o programa!\n"); break;
            default : printf("Opcao invalida!\n"); break;
                
        }
        return opcao;    
    }
    
    
    int main()
    {
        char nomeFicheiro[50];
        printf("Qual o nome do ficheiro a criar? ");
        scanf("%s", nomeFicheiro);
        char auxFicheiro[50];
        sprintf(auxFicheiro, "%s.txt", nomeFicheiro);
        FILE *f;
        f=fopen(auxFicheiro, "r+");
        if(f==NULL)
        {
            printf("Erro\n");
            return 0;
        }    
        int valorMenu;
        do
        {
            valorMenu=Menu(f);
        }while((valorMenu>=1)&&(valorMenu<=4));
        
        
        
        return 0;
    }

  10. #10
    Registered User
    Join Date
    Mar 2010
    Posts
    583
    With "r+" the file is required to exist before fopen is called -- is that what you want? "a+" will create it if it doesn't exist already, but won't clear an existing file.

    I prefer not to keep files open for the whole duration of a program -- opening them and closing them in different modes when needed. Partly so that if the program crashes, it won't keep the file locked open or incomplete.

    For your program it looks reasonable enough to keep the file open throughout. Since input (fgets) also moves the file pointer, you should probably reset the file position with fseek() at the start of Listar rather than the end of Adicionar(), and add an fflush at the end of Adicionar to make sure everything makes it safely to the file.

    You should also have an fclose() when your program ends.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. write vs fprintf
    By Annonymous in forum C Programming
    Replies: 6
    Last Post: 06-10-2011, 06:57 AM
  2. Doesn't write in file when call GetSaveFileName()
    By randall81 in forum Windows Programming
    Replies: 1
    Last Post: 03-28-2009, 01:34 PM
  3. How to write in a file using fscanf and fprintf
    By g_p in forum C Programming
    Replies: 8
    Last Post: 05-24-2007, 01:52 PM
  4. Replies: 4
    Last Post: 10-10-2004, 01:01 AM
  5. Replies: 1
    Last Post: 04-02-2003, 07:50 PM