Skip to main content

Someone wanted to learn this too, so Grasp built them a personal learning path.

You can keep exploring this one or create your own

Saving Struct Arrays to Text Files

Hello! Welcome to our next lesson.

In our previous session, we successfully tackled the challenge of reading structured data from a text file and loading it into an array of structs. We explored how to parse delimited data using both fscanf and the more robust fgets/sscanf combination.

Today, we will complete that data-handling round trip. You'll learn how to take an array of structs that exists in your program's memory and save it to a text file in a clean, structured format. This process, often called serialization, is fundamental for tasks like saving program state, exporting data for other applications, or creating reports. By the end of this lesson, you'll be able to confidently write programs that persist complex data to disk.

1. Introducing fprintf: Your Tool for Writing to Files

Just as fscanf is the file-based counterpart to scanf, the fprintf function is the counterpart to printf. Its purpose is to write formatted text to a file stream instead of to the console.

The function signature is very similar to printf:
int fprintf(FILE *stream, const char *format, ...);

  • stream: A FILE pointer to an open file (e.g., the one returned by fopen).
  • format: The familiar format string with placeholders like %d, %s, and %f.
  • ...: The list of variables to be written, corresponding to the placeholders in the format string.

Let's look at the basic mechanics of writing a few variables to a file.

C fprintf Tutorial: Master Formatted Output with Practical Examples

This article from zetcode provides a clear introduction to fprintf.

Please read the first two sections: "C fprintf" and "Writing Formatted Data to a File." Focus on how fprintf is used just like printf, but with a FILE * as the first argument. Notice the standard sequence: fopen -> fprintf -> fclose.

2. Saving an Array of Structs

Now, let's apply this to our main goal: saving an array of structs. The overall strategy is simple and builds directly on concepts you already know:

  1. Define a struct to model your data and create an array of these structs. For this lesson, we'll populate this array with hardcoded data.
  2. Open a file in write mode ("w") using fopen. This mode creates the file if it doesn't exist or overwrites it completely if it does.
  3. Perform error checking to ensure the file pointer is not NULL.
  4. Loop through the array. For each struct in the array:
    • Call fprintf once, providing a format string that defines how a single line (or record) should look in the file.
  5. Close the file using fclose to ensure all data is written from the buffer to the disk.

The following video provides a complete, practical demonstration of this entire process.

Write An Array Of Structs To A CSV File | C Programming Example

The video "Write An Array Of Structs To A CSV File" by Portfolio Courses walks through a complete example.

Watch the following segments to see each step in action: Setup: See how the student struct and an array are defined. Opening the file: Pay attention to the use of "w" mode and the essential NULL check. Populating data: This section just fills the array with sample data so there is something to write. The writing loop: This is the most important part. Focus on the fprintf call. Notice how the format string "%c,%s,%d,%.2f\n" includes literal commas to create the CSV format and a newline character (\n) to ensure each record is on its own line. Closing the file: The final, crucial step.

As you saw in the video, the magic is all in the format string. By carefully crafting this string, you can generate output in almost any text-based format, from simple logs to more complex structures like CSV, JSON, or XML.

This diagram is a good reminder of the data structure we're working with. Our goal is to take each of these structs from the array (at index 0, 1, 2, etc.) and write its members as a single line in a text file.

3. Writing with Confidence: Error Checking

Just as with reading files, things can go wrong during writing. The disk could be full, or there might be a permissions issue. fprintf returns the number of characters it successfully wrote, or a negative number if an error occurred. It's good practice to check for this, especially in critical applications.

The article we looked at earlier has a section dedicated to this.

C fprintf Tutorial: Master Formatted Output with Practical Examples

This resource demonstrates how to make your file-writing code more robust.

Read the section titled "Error Handling with fprintf". It shows how to check the return value of fprintf to detect write errors. While the video used ferror(), checking the return value of fprintf directly is another common and effective technique.

4. Practical Exercise

Let's apply what you've learned. In the last lesson, you wrote a program to read from an inventory.csv file. Now, you'll write a program to create a similar file from data stored in an array.

Your Task:
Create a C program named write_inventory.c that performs the following steps:

  1. Define the same Product struct as in the previous lesson:
    typedef struct {
        int id;
        char name[50];
        float price;
    } Product;
    
  2. In your main function, create and initialize an array of Product structs with at least three different products.
    // Example initialization
    Product inventory[3] = {
        {101, "Laptop", 999.99f},
        {234, "Mouse", 24.50f},
        {502, "Keyboard", 75.00f}
    };
    int num_products = 3;
    
  3. Open a file named inventory_out.csv in write mode ("w"). Don't forget to check if the fopen call was successful.
  4. (Optional but recommended): Write a header line to the file first. This makes the CSV file easier to understand. For example: fprintf(file_pointer, "ID,Name,Price\n");
  5. Write a for loop that iterates from 0 to num_products - 1.
  6. Inside the loop, use a single fprintf call to write the id, name, and price of the current product to the file. Ensure the output is comma-separated and that each product is on a new line. Format the price to two decimal places.
  7. After the loop, close the file using fclose.
  8. Print a confirmation message to the console, like "Successfully wrote 3 products to inventory_out.csv".

After running your program, open inventory_out.csv in a text editor to verify its contents.

Solution



#include <stdio.h>




#define MAX_NAME_LEN 50

typedef struct {
    int id;
    char name[MAX_NAME_LEN];
    float price;
} Product;

int main() {
    // 1. Create and initialize the data
    Product inventory[3] = {
        {101, "Laptop", 999.99f},
        {234, "Mouse", 24.50f},
        {502, "Keyboard", 75.00f}
    };
    int num_products = 3;

    FILE *file_pointer;

    // 2. Open the file in write mode
    file_pointer = fopen("inventory_out.csv", "w");
    if (file_pointer == NULL) {
        perror("Error opening inventory_out.csv");
        return 1;
    }

    // 3. Write the CSV header
    fprintf(file_pointer, "ID,Name,Price\n");

    // 4. Loop through the array and write each struct
    for (int i = 0; i < num_products; i++) {
        int written = fprintf(file_pointer, "%d,%s,%.2f\n",
                              inventory[i].id,
                              inventory[i].name,
                              inventory[i].price);
        
        // Optional: Check for write errors
        if (written < 0) {
            printf("Error writing record for product ID %d.\n", inventory[i].id);
            break; // Exit the loop on error
        }
    }

    // 5. Close the file
    fclose(file_pointer);

    // 6. Print confirmation
    printf("Successfully wrote %d products to inventory_out.csv\n", num_products);

    return 0;
}

Conclusion

Congratulations! You have now mastered both reading from and writing to files with structured data in C. This is a significant milestone that opens the door to building much more powerful and persistent applications.

Key Takeaways:

  • fprintf is the primary function for writing formatted text to a file, working just like printf but with a FILE* argument.
  • To save an array of structs, you loop through the array and use one fprintf call per element to write a formatted line to the file.
  • The format string in fprintf gives you complete control over the output structure, allowing you to easily create standard formats like CSV.
  • Always open files in the correct mode ("w" to overwrite, "a" to append), check for NULL after fopen, and remember to fclose the file to save all changes.

Preview of the Next Lesson:
With this lesson, we conclude our module on file handling and our foundational tour of the C language. You now have a solid toolkit covering variables, control flow, functions, pointers, memory, and file I/O. We are ready to transition to the second major theme of this course: algorithms. In our next module, we'll start by asking a crucial question: "What makes an algorithm 'good'?" We will introduce the concept of Big-O notation, the essential tool for analyzing and comparing algorithm efficiency.

Can't find a good explanation? Sign up and we'll make it for you

Sign up