#Data Persistence in C.
1 messages · Page 1 of 1 (latest)
@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
-# 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?
Quickly explain how that would compare to the use of JSON in C
-# 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/fprintfis 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 withfscanf/fprintfbecomes a nightmare. JSON requires a library (likecJSONorjson-c) to parse and generate, which adds a bit of setup, but it handles complexity way more gracefully. - Data Structure:
fscanf/fprintfis 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
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
Thank you so much.
You're welcome, lucas! Glad I could help. Let me know if anything else comes up.
So, i've been working on it, but my code doesnt work well and i cant figure out how to fix (i could ask chatgpt or deepseek, sure, but im tryng to avoid AI)
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
@unborn mason briefly, how can I open a file in append mode in C? Do I need to do it manually?
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").
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