fputs or fprintf not writing into a file for strings

Viewed 861

Why fputs() or fprintf() are not writing into the file.txt for %s? I tried both functions but they don't seem to write into the file. However, when using the same functions for %d, it does work currently. As for the expected output versus what currently happens, please find below an example when choosing option 1 in the program, and entering a square side of 2.

Currently happening:

1
2
4
8

Expected output:

You have chosen option: 1
The side of the square is: 2
The square area is: 4
The square perimeter is: 8

Any ideas as to what may be causing this? Thank you!

N.b. This code is for learning purposes, so you may find inconsistencies in the way I work with variables (i.e. passing by reference or value). Please disregard that.

#include <stdio.h> 
#include <locale.h>
#include <string.h>
#define PI 3.14

void square_functions (int side, int *square_perimeter, int *square_area);
float circle_functions (float radius, float * area_circle, float * circumference, FILE *fich);

int main() 
{ 

    float radius, area_circle, circumference;
    int side, square_area, square_perimeter, choice;
    FILE *fich; /* esto como variable global penaliza! */
    fich=fopen("file.txt","w");

    while (1) 
    {
    printf("Enter 1 to calculate the square\n"); 
    printf("Enter 2 to calculate the circumference\n");
    printf("Enter your option:\n"); 
    scanf("%d",&choice);
    fprintf(fich,"%s\n", "You have chosen option:");
    fprintf(fich,"%d\n",choice);

    switch (choice) 
        { 
        case 1: 
            printf("Please enter the side of the square: ");
            scanf("%d", &side);
            fprintf(fich,"%s\n", "The side of the square is:");
            fprintf(fich,"%d\n",side);
            if(side > 0)
            {
                square_functions (side, &square_perimeter, &square_area);
                printf("\nSquare area: %d", square_area);
                printf("\nSquare perimeter: %d\n", square_perimeter);
                fprintf(fich,"%s\n", "The square area is:");
                fprintf(fich,"%d\n", square_area);
                fputs("The square perimeter is",fich);
                fprintf(fich,"%d\n", square_perimeter);
            }
            else
            {
                printf("The value is invalid, the operation has been cancelled");
            } 
        break;

        case 2: 
            printf("\n\nPlease enter the radius fo the circle: ");
            scanf("%f", &radius);

            if(radius > 0)
            {
                circle_functions (radius, &area_circle, &circumference, fich);  
                printf("Circle area: %f", area_circle);
                printf("circumference: %f", circumference);
            }
            else
            {
                printf("The value is invalid, the operation has been cancelled");
            }
        break;
        }
    }
fclose(fich);
return 0;
}

void square_functions (int side, int *square_perimeter, int *square_area)
{       
        *square_perimeter = side * 4;
        *square_area = side * side;
}

float circle_functions (float radius, float * area_circle, float * circumference, FILE *fich) 
{
        *area_circle = PI * radius * radius;
        *circumference = 2 * PI * radius;
        fputs("The area of the circle is",fich); 
        fprintf(fich,"%f\n",*area_circle);
        fputs("The circumference is",fich);
        fprintf(fich,"%f\n",*circumference);
        return 0;       
}
5 Answers

The problem is you're not closing the file. Note: You have fclose(fich);, but it's unreachable. Add a third condition, such as the following, at it should work:

case 3:
    fclose(fich);
    return 0;

An alternative would be to not use an infinite loop (while(1)) and use a condition instead. For example:

bool run = true;
while(run)
{
    ...
    case 3:
        run = false;
        break;
    ...
}

Why not try fprintf(fich,"The square area is:\n");

Your code as is, is fairly complete, but requires a few adjustments

  • Requires a way to exit,

  • In the second case (circles) the function printf() is used as opposed to fprintf().

  • fclose() is never accessed due to infinite loop

The following addresses these, by using a boolean variable running as a flag to run, and a third case to access it to exit, and adds the fprintf function in the second case, and opens/closes file each iteration:

#define FILENAME "file.txt" 

int main(void) 
{ 
    float radius, area_circle, circumference;
    int side, square_area, square_perimeter, choice;
    BOOL running = TRUE;
    FILE *fich; /* esto como variable global penaliza! */
    //create file for write:
    fich=fopen(FILENAME,"w");//test before using
    if(fich)
    {
        fprintf(fich, "Beginning of file:\n\n");
        fclose(fich);
    }

    while (running) 
    {
        printf("Enter 1 to calculate the square\n"); 
        printf("Enter 2 to calculate the circumference\n");
        printf("Enter 3 to quit program\n");        
        printf("Enter your option:\n"); 
        scanf("%d",&choice);
        fprintf(fich,"%d\n",choice);

        switch (choice) 
        { 
        case 1: 
            fich=fopen(FILENAME,"a");//test before using
            if(fich)
            {
                printf("Please enter the side of the square: ");
                scanf("%d", &side);
                fprintf(fich,"%d\n",side);
                if(side > 0)
                {
                    square_functions (side, &square_perimeter, &square_area);
                    printf("\nSquare area: %d", square_area);
                    printf("\nSquare perimeter: %d\n", square_perimeter);
                    fprintf(fich,"%s\n", "The square area is: %d\n");
                    fprintf(fich,"The perimeter is: %d\n", square_perimeter);
                }               
                else
                {
                    printf("The value is invalid, the operation has been cancelled");
                }
                fclose(fich);
            }
            break;

        case 2: 
            fich=fopen(FILENAME,"a");//test before using
            if(fich)
            {
                printf("\n\nPlease enter the radius of the circle: ");
                scanf("%f", &radius);

                if(radius > 0)
                {
                    circle_functions (radius, &area_circle, &circumference, fich);  
                    printf("Circle area: %f", area_circle);
                    printf("circumference: %f", circumference);
                    fprintf(fich, "Circle area: %f", area_circle);
                    fprintf(fich, "circumference: %f", circumference);
                }
                else
                {
                    printf("The value is invalid, the operation has been cancelled");
                }
                fclose(fich);
            }
            break;
        case 3:
            running = FALSE;
            break;
        }
    }
    return 0;
}

When I run the program on Microsoft Windows, the output to stdout works, but not the output to fich. The problem is that (at least with me), stdout is line buffered, whereas fich is fully buffered. Since you never call fclose (because it is outside the infinite loop), the buffer of fich never gets flushed.

To fix this problem, you can either explicitly flush the buffer with fflush( fich ); or you can implicitly flush the buffer, by ensuring that fclose gets called (for example by exiting the loop).

Alternatively, you can disable buffering completely, by calling setbuf( fich, NULL); Please note that this line must appear immediately after the call to fopen. See the documentation on the function setbuf for further information. However, this should normally not be done, because buffering can be important for performance.

Thanks to @AndreasWenzel comments I have added below the final pieces of code that work; first version using fclose(fich); and second one using fflush(fich);.

fclose(fich); version: the file is being closed every time is opened to write in it.

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

#define PI 3.14

void square_functions (double side, double *square_perimeter, double *square_area);
void circle_functions (double radius, double *area_circle, double *circumference);

int main() 
{ 

    double radius, area_circle, circumference, side, square_area, square_perimeter;
    int choice;
    FILE *fich;

    while (1) 
    {
    printf("\nEnter 1 to calculate the square"); 
    printf("\nEnter 2 to calculate the circumference");
    printf("\nEnter your option:"); 
    scanf("%d",&choice);
    fich = fopen("file.txt","a+");
    fprintf(fich,"%s", "\n\nThe option chosen is: ");
    fprintf(fich,"%d\n",choice);
    fclose(fich);

    switch (choice) 
        { 
        case 1:
            printf("Please enter the side of the square: ");
            scanf("%lf", &side);
            fich = fopen("file.txt","a+");
            fprintf(fich,"%s", "\nThe side of the square is: ");
            fprintf(fich,"%lf",side);
            if(side > 0)
            {
            square_functions (side, &square_perimeter, &square_area);
            printf("\nSquare area: %lf", square_area);
            printf("\nSquare perimeter: %lf\n", square_perimeter);  
            fprintf(fich,"%s", "\nThe square area is: ");
            fprintf(fich,"%lf", square_area);
            fprintf(fich,"%s", "\nThe square perimeter is: ");
            fprintf(fich,"%lf", square_perimeter);
            fclose(fich);
            }
            else
            {
            printf("The value is invalid, the operation has been cancelled");
            } 
        break;

        case 2:
            printf("\n\nPlease enter the radius fo the circle: ");
            scanf("%lf", &radius);
            fich = fopen("file.txt","a+");
            fprintf(fich,"%s", "\nThe radius of the circle is: ");
            fprintf(fich,"%lf",radius);         
            if(radius > 0)
            {
            circle_functions (radius, &area_circle, &circumference);       
            printf("\nCircle area: %lf\n", area_circle);
            printf("\nCircumference: %lf\n", circumference);
            fprintf(fich,"%s", "\nThe circle area is: ");
            fprintf(fich,"%lf",area_circle);
            fprintf(fich,"%s", "\nThe circumference is: ");
            fprintf(fich,"%lf",circumference);
            fclose(fich);
            }
            else
            {
            printf("The value is invalid, the operation has been cancelled");
            }
        break;
        }
    }
return 0;
}

void square_functions (double side, double *square_perimeter, double *square_area)
{       
        *square_perimeter = side * 4;
        *square_area = side * side;
}

void circle_functions (double radius, double *area_circle, double *circumference) 
{
        *area_circle = PI * radius * radius;
        *circumference = 2 * PI * radius;   
}

fflush(fich); version: the buffer is flushed immediately before the switch statement and once immediately after the switch statement (as the last statement of the while loop).

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

#define PI 3.14

void square_functions (double side, double *square_perimeter, double *square_area);
void circle_functions (double radius, double *area_circle, double *circumference);

int main() 
{ 

    double radius, area_circle, circumference, side, square_area, square_perimeter;
    int choice;
    FILE *fich;
    fich = fopen("file.txt","a+");

    while (1) 
    {
    printf("\nEnter 1 to calculate the square"); 
    printf("\nEnter 2 to calculate the circumference");
    printf("\nEnter your option:"); 
    scanf("%d",&choice);
    fprintf(fich,"%s", "\n\nThe option chosen is: ");
    fprintf(fich,"%d\n",choice);
    fflush( fich );

    switch (choice) 
        { 
        case 1:
            printf("Please enter the side of the square: ");
            scanf("%lf", &side);
            fprintf(fich,"%s", "\nThe side of the square is: ");
            fprintf(fich,"%lf",side);
            if(side > 0)
            {
            square_functions (side, &square_perimeter, &square_area);
            printf("\nSquare area: %lf", square_area);
            printf("\nSquare perimeter: %lf\n", square_perimeter);  
            fprintf(fich,"%s", "\nThe square area is: ");
            fprintf(fich,"%lf", square_area);
            fprintf(fich,"%s", "\nThe square perimeter is: ");
            fprintf(fich,"%lf", square_perimeter);
            }
            else
            {
            printf("The value is invalid, the operation has been cancelled");
            } 
        break;

        case 2:
            printf("\n\nPlease enter the radius fo the circle: ");
            scanf("%lf", &radius);
            fprintf(fich,"%s", "\nThe radius of the circle is: ");
            fprintf(fich,"%lf",radius);         
            if(radius > 0)
            {
            circle_functions (radius, &area_circle, &circumference);       
            printf("\nCircle area: %lf\n", area_circle);
            printf("\nCircumference: %lf\n", circumference);
            fprintf(fich,"%s", "\nThe circle area is: ");
            fprintf(fich,"%lf",area_circle);
            fprintf(fich,"%s", "\nThe circumference is: ");
            fprintf(fich,"%lf",circumference);
            }
            else
            {
            printf("The value is invalid, the operation has been cancelled");
            }
        break;
        }
    fflush( fich );
    }
return 0;
}

void square_functions (double side, double *square_perimeter, double *square_area)
{       
        *square_perimeter = side * 4;
        *square_area = side * side;
}

void circle_functions (double radius, double *area_circle, double *circumference) 
{
        *area_circle = PI * radius * radius;
        *circumference = 2 * PI * radius;   
}
Related