#Data Persistence in C.

1 messages · Page 1 of 1 (latest)

unborn masonBOT
#

-# C @terse latch @zenith yacht

violet pine
#

@unborn mason please show an example of using fscanf/fprintf to read/write values to a file.

Also briefly explain how this differs from using JSON in C

unborn masonBOT
#

-# Writing a response for "File I/O in C using fscanf/fprintf and comparison with JSON"

#

Hey there! Let's dive into file I/O in C with fscanf and fprintf. These are super handy for reading and writing structured text data.

Writing to a File with fprintf

Think of fprintf as the file version of printf. Instead of printing to the console, it writes formatted data to a file.

Here's a quick example:

#include <stdio.h>

int main() {
    FILE *outFile = fopen("data.txt", "w"); // "w" for write mode

    if (outFile == NULL) {
        perror("Error opening file for writing");
        return 1;
    }

    int id = 101;
    char name[] = "Alice";
    float score = 95.5;

    fprintf(outFile, "ID: %d\n", id);
    fprintf(outFile, "Name: %s\n", name);
    fprintf(outFile, "Score: %.2f\n", score);

    fclose(outFile); // Always close your files!
    printf("Data written to data.txt\n");
    return 0;
}

When you run this, it'll create a file named data.txt with the content:

ID: 101
Name: Alice
Score: 95.50

The "w" mode creates the file if it doesn't exist or overwrites it if it does.

Reading from a File with fscanf

fscanf is the file counterpart to scanf. It reads formatted input from a file, matching it against a format string.

Let's read the data.txt we just created:

#include <stdio.h>

int main() {
    FILE *inFile = fopen("data.txt", "r"); // "r" for read mode

    if (inFile == NULL) {
        perror("Error opening file for reading");
        return 1;
    }

    int readId;
    char readName[50]; // Make sure this buffer is large enough!
    float readScore;

    // We need to read line by line or use format specifiers carefully
    // This example assumes the format is consistent
    fscanf(inFile, "ID: %d\n", &readId);
    fscanf(inFile, "Name: %s\n", readName);
    fscanf(inFile, "Score: %f\n", &readScore);

    fclose(inFile);

    printf("Read from

...(response truncated to fit Discord's limit)

I had to truncate the response due to length limits. Would you like me to send the rest?
violet pine
#

Quickly explain how that would compare to the use of JSON in C

unborn masonBOT
#

-# Writing a response for "Comparison of C file I/O (fscanf/fprintf) with JSON for data persistence"

#

Okay, so you've got the lowdown on fscanf and fprintf for C file I/O. Now, let's chat about how using JSON for data persistence in C stacks up against that.

Think of fscanf/fprintf as the super basic, raw way to save stuff. You're essentially writing data out in a format that you define, often line by line or with specific delimiters. It's like writing notes in a personal shorthand – fast and direct for simple things, but a pain if someone else needs to read it without your key.

JSON, on the other hand, is a structured data format. It's human-readable and designed to represent complex data relationships. Instead of just dumping values, JSON uses key-value pairs and arrays, making it way easier to represent objects, lists, and nested data.

Here are the key differences:

  • Complexity: fscanf/fprintf is simpler to implement for very basic data (like a few numbers or strings). But as your data gets more complex, managing the format, parsing it back correctly, and handling errors with fscanf/fprintf becomes a nightmare. JSON requires a library (like cJSON or json-c) to parse and generate, which adds a bit of setup, but it handles complexity way more gracefully.
  • Data Structure: fscanf/fprintf is flat. You're mostly dealing with sequences of values. JSON excels at representing hierarchical data – think of a user object with a name, age, and a list of their hobbies. You can easily nest JSON objects within objects.
  • Use Cases:
    • fscanf/fprintf: Best for simple configuration files, raw data dumps where you control both reading and writing, or when you absolutely cannot use external libraries.
    • JSON: Ideal for configuration files that need to be human-editable, data exchange between different applications or services (APIs often use JSON), and when you h
violet pine
#

Using fscanf and fprintf are the easiest approach and fairly flexible. Using JSON in C will be a bit more complex.

If you’re storing just strings you could put one on each line, that’d be even simpler

raven hull
#

Thank you so much.

unborn masonBOT
#

You're welcome, lucas! Glad I could help. Let me know if anything else comes up.

raven hull
#

void save_data()
{
FILE * data_file = fopen("data.txt", "w");

for (int i = 0; i < task_counter; i++) // percorre a lista
{
    fprintf(data_file, "%s\n", todo_list[i]);
}

fclose(data_file);

}

void load_data()
{
FILE * data_file = fopen("data.txt", "r");

char task[MAX_CHARS];
for (int i = 0; i < task_counter; i++)
{
    while (fgets(task, MAX_CHARS, data_file))
    {
        printf("%s", task);
    }
}

fclose(data_file);

}

#

the functions:

#

the problem is: If I add another task, this new task will overwrite the old one

violet pine
#

@unborn mason briefly, how can I open a file in append mode in C? Do I need to do it manually?

unborn masonBOT
#

Hey lucas, I see you're having trouble with file persistence in C.

For your save_data function, the issue with overwriting is because you're opening the file in "w" (write) mode. This mode truncates the file if it exists. To add tasks without overwriting, you should open the file in "a" (append) mode. So, change fopen("data.txt", "w") to fopen("data.txt", "a").

Your load_data function has a nested loop that's causing problems. The outer for loop iterates task_counter times, and the inner while (fgets(...)) reads the file. This will read the whole file multiple times. A simpler way to load is to just read line by line until the end of the file and update your task_counter accordingly. Here's a corrected version:

void load_data() {
    FILE *data_file = fopen("data.txt", "r");
    if (data_file == NULL) {
        // Handle error: file not found or cannot be opened
        return;
    }
    char task[MAX_CHARS]; // Ensure MAX_CHARS is defined
    int i = 0;
    // Read line by line until end of file or max tasks reached
    while (fgets(task, MAX_CHARS, data_file) && i < MAX_TASKS) { // Ensure MAX_TASKS is defined and todo_list is sized appropriately
        // Remove trailing newline character if present
        task[strcspn(task, "\n")] = 0;
        strcpy(todo_list[i], task); // Assuming todo_list is an array of char arrays or similar
        i++;
    }
    task_counter = i; // Update the global task_counter
    fclose(data_file);
}

And to answer your question, Zech: yes, you open a file in append mode in C by using fopen("filename.txt", "a").

violet pine
#

Thanks smarter dev, you can stop now.

#

That was less brief than I was hoping for but yeah, the issue is when you open a file in w mode it overwrites the entire file. Using a mode will add anything you fprintf to the end of the file.

Ideally you’d probably want to read the contents of the file then modify that and write it back, in C this can be a bit harder to accomplish though