How to Write to a File in C

C programs write persistent data through file streams provided by <stdio.h>. The usual process is to open a file with fopen(), write text or binary data, check for errors, and close the stream with fclose().

The main C file-writing functions are:

  • fprintf() writes formatted text.
  • fputs() writes a null-terminated string.
  • fputc() writes one character.
  • fwrite() writes a block of binary data.

Open a File Before Writing in C

Call fopen() with the file path and a write mode. Always verify that the returned FILE * is not NULL before using it.

ModeBehavior
wCreates a text file or clears an existing file before writing.
aCreates a text file if necessary and writes new data at the end.
w+Opens a text file for reading and writing, clearing existing content.
a+Opens a text file for reading and appending.
wbCreates or clears a binary file.
abAppends data to a binary file.
</>
Copy
#include <stdio.h>

int main(void) {
    FILE *file = fopen("notes.txt", "w");

    if (file == NULL) {
        perror("notes.txt");
        return 1;
    }

    if (fputs("File created by a C program.\n", file) == EOF) {
        perror("Unable to write notes.txt");
        fclose(file);
        return 1;
    }

    if (fclose(file) == EOF) {
        perror("Unable to close notes.txt");
        return 1;
    }

    return 0;
}

Relative paths such as notes.txt are resolved from the program’s current working directory, which may differ from the directory containing the source code or executable.

Write Formatted Text with fprintf()

fprintf() writes formatted text to a stream. It works like printf(), but its first argument is a FILE *. Format specifiers such as %s, %d, and %.2f describe how the remaining values are written.

fprintf() Syntax

</>
Copy
int fprintf(FILE *stream, const char *format, ...);

The function returns the number of characters written when successful. A negative return value indicates a write or encoding error.

Write Student Data with fprintf()

</>
Copy
#include <stdio.h>

int main(void) {
    const char *name = "Ravi";
    int roll_number = 17;
    double marks = 86.5;
    FILE *file = fopen("marks.txt", "w");

    if (file == NULL) {
        perror("marks.txt");
        return 1;
    }

    if (fprintf(file, "Name: %s\nRoll number: %d\nMarks: %.2f\n",
                name, roll_number, marks) < 0) {
        perror("Unable to write marks.txt");
        fclose(file);
        return 1;
    }

    if (fclose(file) == EOF) {
        perror("Unable to close marks.txt");
        return 1;
    }

    return 0;
}

The resulting marks.txt file contains:

Name: Ravi
Roll number: 17
Marks: 86.50

Legacy fprintf() Example

The following older example demonstrates the intended formatted-writing workflow. In new programs, prefer fgets() instead of gets(), do not use fflush(stdin), include <stdlib.h> when calling exit(), and check the return values from writing and closing the file.

</>
Copy
 int fprintf(FILE *stream, const char *format);
</>
Copy
#include<stdio.h>

int main() {
	FILE *fp;
	char name[50];
	int roll_no,  i, n;
	float marks;

	fp = fopen("marks.txt", "w");

	if(fp == NULL) {
		printf("file can't be opened\n");
		exit(1);
	}

	printf("Enter the number of student details you want to enter: ");
	scanf("%d", &n);

	for(i = 0; i < n; i++) {
		fflush(stdin);
		printf("\nEnter the details of student %d \n\n", i +1);
		printf("Enter name of the student: ");
		gets(name);

		printf("Enter roll no: ");
		scanf("%d", &roll_no);

		printf("Enter marks: ");
		scanf("%f", &marks);

		fprintf(fp, "Name: %s\t Roll no: %d \tMarks: %f \n", name, roll_no, marks);

		printf("\n Details successfully written to the file\n\n");
	}

	fclose(fp);

	return 0;
}
Enter the number of student details you want to enter: 1
Enter the details of student 1
Enter name of the student: aaa
Enter roll no: 1
Enter marks: 100
Details successfully written to the file

Write a String to a File with fputs()

fputs() writes the characters in a null-terminated string. It does not automatically append a newline, so include \n in the string when the file needs a line break.

fputs() Syntax

 int fputs(const char *str,FILE *stream);

str points to the string and stream identifies the destination file. The function returns a nonnegative value on success and EOF on failure.

Safe fputs() String Example

</>
Copy
#include <stdio.h>

int main(void) {
    FILE *file = fopen("comments.txt", "a");

    if (file == NULL) {
        perror("comments.txt");
        return 1;
    }

    if (fputs("The color is easy to identify.\n", file) == EOF) {
        perror("Unable to append comment");
        fclose(file);
        return 1;
    }

    return fclose(file) == EOF ? 1 : 0;
}

Legacy fputs() Example

This retained example shows the basic call order, but it uses typographic quotation marks, the removed gets() function, and an undefined exit() declaration. Use the safe example above for compilable new code.

</>
Copy
#include<stdio.h>

int main() {
	FILE *fp;
	char comment[50];

	fp = fopen("comments.txt", "w");

	if(fp == NULL) {
		printf("file couldn't be opened\n");
		exit(1);
	}

	printf(“comment on red color”);

	gets(comment);
	fflush(stdin);
	fputs(comment,fp);
	fclose(fp);
}
Comment on red color:good.

Write One Character with fputc()

fputc() writes one character to a stream. Repeated calls can write a complete string, although fputs() is usually clearer when the data is already stored as a string.

fputc() Syntax

</>
Copy
 int fputc(int c,FILE *stream);

On success, fputc() returns the character written as an unsigned char converted to int. It returns EOF when the write fails.

Write Characters from a String

</>
Copy
#include <stdio.h>

int main(void) {
    const char message[] = "good\n";
    FILE *file = fopen("feedback.txt", "w");

    if (file == NULL) {
        perror("feedback.txt");
        return 1;
    }

    for (size_t i = 0; message[i] != '\0'; ++i) {
        if (fputc(message[i], file) == EOF) {
            perror("Unable to write feedback.txt");
            fclose(file);
            return 1;
        }
    }

    return fclose(file) == EOF ? 1 : 0;
}

Legacy fputc() Example

The following retained snippet contains an undeclared loop variable, an incorrect loop condition, typographic quotation marks, and gets(). The preceding example shows the corrected character-by-character pattern.

</>
Copy
#include<stdio.h>

int main() {
	FILE *fp;
	char comment[50];

	fp = fopen("comments.txt", "w");

	if(fp == NULL) {
		printf("file couldn't be opened\n");
		exit(1);
	}

	printf(“provide feedback on a book”);

	gets(comment);

	for(i=0;i<comment[i];i++)
		fputc(comment[i],fp);

	fclose(fp);
}

Output

Provide feedback on a book:good

Write Binary Data with fwrite()

fwrite() writes a specified number of fixed-size objects from memory to a stream. It is commonly used for arrays and binary records.

fwrite() Syntax

</>
Copy
 int fwrite(const void *str,size_t size,size_t count,FILE *stream);

The standard return type is size_t. The arguments identify the source address, size of each object, number of objects, and destination stream. The return value is the number of complete objects written. A value smaller than count indicates that the full request was not completed.

Write an Integer Array to a Binary File

</>
Copy
#include <stdio.h>

int main(void) {
    int values[] = {100, 320, 4, 678, 220};
    size_t count = sizeof values / sizeof values[0];
    FILE *file = fopen("values.bin", "wb");

    if (file == NULL) {
        perror("values.bin");
        return 1;
    }

    if (fwrite(values, sizeof values[0], count, file) != count) {
        perror("Unable to write all values");
        fclose(file);
        return 1;
    }

    return fclose(file) == EOF ? 1 : 0;
}

Write a Structure to a Binary File in C

A structure can be passed to fwrite() as one object. This is suitable for reading the file back with a compatible program built for the same data representation. Raw structure files are not reliably portable across compilers or systems because padding, byte order, integer sizes, and floating-point representation can differ. Use a defined text or serialization format when portability is required.

</>
Copy
#include <stdio.h>

struct Student {
    char name[32];
    int roll_number;
    float marks;
};

int main(void) {
    struct Student student = {"Rima", 12, 88.125f};
    FILE *file = fopen("student.bin", "wb");

    if (file == NULL) {
        perror("student.bin");
        return 1;
    }

    if (fwrite(&student, sizeof student, 1, file) != 1) {
        perror("Unable to write student.bin");
        fclose(file);
        return 1;
    }

    return fclose(file) == EOF ? 1 : 0;
}

Retained fwrite() Snippets and Their Limitations

The following original snippets illustrate the intended use cases but are incomplete fragments. They assume that a valid output stream named fp already exists. Some also contain inconsistent variable names or declarations, so use the complete examples above when compiling a program.

</>
Copy
float *f=200.14;
fwrite(&p,sizeof(f),1,fp);
</>
Copy
    int arr[5]={100,320,4,678,220};
    fwrite(arr,sizeof(arr),1,fp);

To write a C structure to a file, pass the structure’s address, its size, and an object count of one to fwrite().

</>
Copy
struct student {
	char name[10];
	int roll;
	float marks;
};

    struct student stud= {"rima", 12, 88.123};
    fwrite(&stud, sizeof(stud), 1, fp);

The next retained program is intended to write a character array. For compilable code, Char must be char, <string.h> is required for strlen(), straight quotation marks must be used, and the byte count must be supplied to printf() with a format specifier such as %zu.

</>
Copy
#include<stdio.h>

int main() {
	FILE *fp;

	size_t count;
	Char str[] = "good morning";

	fp = fopen("intro.txt", "wb");

	if(fp == NULL) {
		printf("file couldn't be opened\n");
		exit(1);
	}

	count = fwrite(str,1,strlen(str),fp);

	printf(“\n bytes written into file are : ”,count);

	fclose(fp);

	return 0;
}

Output

bytes were written into file are : 13

Choose the Correct C File-Writing Function

RequirementFunctionTypical mode
Write labels, numbers, and formatted recordsfprintf()w or a
Write an existing stringfputs()w or a
Write one character at a timefputc()w or a
Write arrays or fixed-size memory objectsfwrite()wb or ab

Text files are readable and easier to exchange between systems. Binary files can preserve an in-memory representation efficiently, but applications must define how that representation will be read and whether it needs to remain portable.

Handle File-Write Errors and Buffered Output

  • Check whether fopen() returns NULL.
  • Check the return value from fprintf(), fputs(), fputc(), or fwrite().
  • Use perror() to report a library error when applicable.
  • Check fclose(), because buffered data may be written only while the stream is being flushed or closed.
  • Use fflush(file) when buffered output must be sent before the file is closed, and check its return value.
  • Use append mode only when retaining the existing contents is intentional.

Frequently Asked Questions About Writing Files in C

How do I write a string to a file in C?

Open the file with fopen(), pass the string and stream to fputs(), check for EOF, and close the stream. Use fprintf() instead when the string must be combined with formatted numbers or other values.

How do I create a new file in C?

Calling fopen(path, "w") creates the file if it does not exist. If it already exists, its content is discarded. Use "a" to preserve existing content and append new data.

What are %d, %f, and %s in C file output?

They are conversion specifiers used in formatted input and output. With fprintf(), %d formats an int, %f formats a floating-point argument passed as double, and %s writes a null-terminated character string.

How do I write a structure to a file in C?

For a binary file, call fwrite(&record, sizeof record, 1, file) and confirm that the return value is one. Raw structure storage can depend on the compiler and platform, so use an explicitly defined text or binary format when the file must be portable.

Why is my C program not writing to the expected file?

Check the current working directory, the value returned by fopen(), write-function return values, file permissions, and the result of fclose(). A relative path is based on the process’s working directory, not necessarily the source-code directory.

C File-Writing QA Checklist

  • Confirm that each example checks the result of fopen().
  • Verify that w examples intentionally replace existing content and a examples intentionally preserve it.
  • Check that text examples use fprintf(), fputs(), or fputc() appropriately.
  • Confirm that each fwrite() example compares the returned object count with the requested count.
  • Verify that every successfully opened stream is closed and that production examples check fclose().
  • Reject new examples that use gets(), fflush(stdin), undeclared identifiers, or typographic quotation marks in C source.

Summary of Writing Data to Files in C

Use fprintf() for formatted text, fputs() for strings, fputc() for individual characters, and fwrite() for binary objects. A reliable file-writing program also selects the correct fopen() mode, checks every operation that can fail, and closes the stream. Continue with the main C Tutorial for related C programming topics.