C File Save and Restore input information - c

I have a program based on a struct with different information.
In this program you can for example add people and delete people etc. I already have all this done, so the program it self is done. But the files are not.
So I am trying to write a code that "saves" if I would for example add a person and this would "save" when I choose to exit the program. And a code that "restores" the people in the file in the beginning of the program.
Does any one have any ideas or tips? I'm new to programming and trying to learn. I have been sitting with this for a few days.
Before I "restore" I ask for an file to open and if this file does not exist a new one is created and this works. So if I would have a file with 3 employees and I would open this file I would want to restore them and then being able to add more employees to the file etc.

You have to write (and to read) in two steps: first the struct, and then the array the struct points to.
Code fragment for writing (a.o. without error checking, that is however needed):
#include <stdio.h>
// ...
employees emp;
const char* filename="your_filename";
// populate emp;
FILE* file = fopen(filename,"w");
fwrite(&emp,sizeof(employees),1,file);
fwrite(emp.pic,sizeof(int),emp.imageCount,file);
fclose(file);
Now you have the array after the struct in your file. Read it in the same way:
FILE* file = fopen(filename,"r");
fread(&emp,sizeof(employees),1,file);
emp.pic=calloc(sizeof(int), emp.imageCount);
fread(emp.pic,sizeof(int),emp.imageCount,file);
Please don't forget to check for errors (see man fopen|fread|fwrite|calloc). In case you have several structs, you must repeat the two steps for any element.

What is the platform? For Windows there is simple format of .INI files with contents like:
[Employee_1]
id=123
name=Smith
imageCount=2
...
You can use GetPrivateProfileString/GetPrivateProfileInt and WritePrivateProfileString API functions to read and store the information. Use separate section for each employee. One common section is necessary to store the number of employee sections.

Related

Function that creates a different csv file every time it is run

I am making a c program that can save matrices and vectors in CSV files so I can then perform operations between them. In one of my functions I create a matrix with random numbers and then save it inside a CSV file.
The problem is that I don't know how to create a different file every time the function is run so each array can be stored in a different CSV file. Because of this I have to save all the matrices inside the same file which makes the rest of the process a lot harder. How could I make the function that makes a different file every time without it having completely random names.
Here is a link to the project in replit
How could i make the function that makes a different file every time without it having completely random names.
Some possible solutions:
use timestamp as part of filename
use counter
For a timestamp, example code:
char filename[80];
snprintf(filename, sizeof(filename), "prefix.%d", time(NULL));
FILE *fout = fopen(filename, "wt");
For a counter, use the same code as above, but check if the file prefix.${counter} exists (see man access). If it does, increment the counter and try again. If it doesn't, use the filename.

Linking separate C programs together

I'm need some help on a project, the plan is to make a C program that can take an input file name and then do these three tasks:
copy it's contents and store it's duplicate in another user specified location
change the backup file's format, i.e from ".txt" to something like ".img"
encrypt the contents of the file (any cypher method)
Note: the input file name has to be scanned during execution
I and my team have already made about 75% of it but it's in separate parts like each of the following three tasks is an individual program,
and we are having trouble combining them.
Another error is that we are using "rename" function from files concept to copy files and change their format and we don't have any idea of how to use scanf to read the file name and give it as input to the rename function.
So if you could give me any suggestions..I'd really be grateful.
It's been a little while since I've used it, but you could consider using make and creating a makefile. According to what I have seen from the references I've looked up, a basic makefile looks kind of like this.
makefile.h:
basicMakefile: basicMake1.c, basicMake2.c, basicMake3.c
gcc -o basicMakefile basicMake1.c basicMake2.c basicMake3.c -I
As for using scanf, suppose we have
char str1[20]; //creates a char array(a string) that is 20 chars long
printf("Enter the new name for the file: ");
scanf("%s" , str1); //puts the user entered value into str1
you could then do
rename(str1) //function call with the new filename
//whatever your rename funtion does for the logic
Below are the references that I used, I would strongly recommend taking a more in-depth look at these as they explain these concepts in more detail than what I could fit in here. My above examples are derived from the ones found in them.
Make Documentation: https://www.gnu.org/software/make/manual/make.html
Scanf Tutorial: https://www.tutorialspoint.com/c_standard_library/c_function_scanf.htm
Simple Makefile Tutorial: http://www.cs.colby.edu/maxwell/courses/tutorials/maketutor/

How to create file for any user(any computer) desktop in c ?

I am trying to write a c program that creates a file for any computer user. But my program only works for my current user. Not for all users. How can i solve it? I am using windows 10. Please help me.
FILE *fpt;
fpt = fopen("C:\\Users\\Zobayer\\Desktop\\C File IO\\example.txt","r");
I'm sure there's a more simple windows-based way of doing this, but you could just keep an array of all users on your machine that you want to add the file to.
Pseudo code here, but where you need write to the file in your program it'd be something like this:
char ** listofusers = {"Zobayer","Tim","Andrea"};
for (i=0;i<sizeof(listofusers);i++) {
writeToUsersDesktop(listofusers[i]);
}
and then writeToUsersDesktop() would just take the user's name and format it to a string something like "C:\\Users\\\s\\Desktop\\SomeCommonFolder"
Then it would take that string and use it as an argument in fopen()
NOTE: This is not a safe way of doing this if you're asking for user input for the list of users unless you sanitize the usernames first.

C - Deleting / Modifiying A line From A File

I have a datas.txt file :
format : name surname debt payment
bir bir 100 2
iki iki 200 2
eray alakese 100 5
john doe 2000 10
I'm learning C and i know just simple file functions (fscanf, fprinf, fopen etc.)
I'll
ask user name and surname with scanfand then assign them to name and surname variables.
It will search file for name and surname and then assign debt and payment to debt, payment variables ( fscanf(file, "%s %s %d %d", name, surname, &debt, &payment);)
Delete or modify this line
This is my source code .
scanf("%s", &name);
scanf("%s", &surname);
file = fopen("datas.txt", "r");
/* this fscanf() is working as expected. There is no problem. */
fscanf(file, "%s %s %d %d", name, surname, &debt, &payment);
/* modify and delete actions here */
fclose(file);
Examples :
I want to delete record of "John Doe" .
I want to decrease "John Doe"'s debt to 100$
You cannot delete/modify[*] individual lines of a text file; the only solution is to 1) create a new temporary file, 2) copy the contents up to, but not including, the line that you want modified/deleted, 3) output the modified line, 4) copy the rest of the original file, 5) replace the old file with the temporary file.
[*] Modification is possible ONLY if the modified line has the same length as the original line.
EDIT: PS: Using fgets, followed by sscanf (or some other way of tokenizing the line) will save you much grief.
This is a little hard to do, because C's model of files, inherited from Unix (they were largely codeveloped), does not actually define a file as a list of lines. Instead, it defines a line as a string of bytes terminated with a newline, and a file (roughly) as a stored string of bytes of potentially limited length, where you can possibly skip to different parts. That's considerably vague, but bear with me.
Whe problem becomes clearer when we try to translate our ideas - "modify this line", "delete that line" - into file operations. We can read a line by just stopping at a newline, but there's simply no command to cut it into sections; only to set the end (ftruncate()). So to change the size of the line, we need to copy all the data that follows it. It can be done, but it's very often easier to just create the file anew. Compare the subtleties of implementing memmove().
The traditional method to do this comes in two variants, depending on what side effects you can tolerate.
One is to write your updated version in another file, and then rename() it into place. This has the advantage that the new file will be complete by the time you put it in place, but the downsides that it may not match the old file precisely as far as permissions etc go, and it won't be visible to other programs that already had the old one open. If two programs modify the file like this, it's a race condition as one of the changes gets overwritten by the other.
The other is to load the data completely and write the modified version down in place. This means the file itself remains in place, permissions and all, but there will be a duration while you're saving that it is a mix of old and new contents. Text editors tend to do this, often whilst saving the old contents as a separate file in case something goes wrong.
There are tools to manage the side effects too, such as versioned filesystems, file locking, and even libraries prepared for parallel changes (metakit comes to mind). Most of the time we'll be using tools that are already around, like sed -i.
In order to delete or alter a line, you have to "shift" everything after it. For example, consider these two files:
bir bir 100 2 bytes 0-14
iki iki 200 2 bytes 15-29
eray alakese 100 5 bytes 30-49
john doe 2000 10 bytes 50-67
and
bir bir 100 2 bytes 0-14
iki iki 200 2 bytes 15-29
john doe 2000 10 bytes 30-57 <-- byte offsets have changed
This is certainly possible to do, but it's pretty complicated to support in general (you'd have to do a lot of seeks and tells). The more usual approach is to effectively copy the file: you read in from your input-file and print everything out to an output-file, making the modifications you need. (For example, to "delete" a line, you simply don't print that line.) Then, at the end, after closing both files, you "rename" the output-file to overwrite the input-file. This is the approach that command-line utilities such as sed and perl use when instructed to modify a file "in-place".
The usual thing to do is to read all of the file and write all of it back to a temporary file, then delete the original and rename the temporary.
/* pseudo-code!! */
fopen();
while (fscanf(source, ...)) {
/* massage data */
fprintf(temporary, ...);
}
fclose();
remove(source);
rename(temporary, source);
The way I usually handle something like this is to write a function that can "read in" your data and store it to some structure. Then a function to write data from the structure to a file.
This way you can just manipulate the data in an array. This also makes your program more extensible to doing things like sorting, or extra math that you couldnt have done by just writing over the top of the file.
e.g. try writing a function that can read in to a struct like:
struct Client
{
char name[255];
double owes;
double paid;
}
What you then do make an array of these structures and manipulate those.
You'll learn a lot about structs, dynamic memory allocation, and you'll no doubt run in to some interesting issues that will help you learn.
My advice is to also skip C and go for C++... learning this stuff using iostreams instead of the *printf/*scanf functions and vectors is probably going to be better for you in the long run

How to replace a line on the middle of a txt file in C?

I am reading info (numbers) from a txt file and after that I am adding to those numbers, others I had in another file, with the same structure.
At the start of each line in the file is a number, that identifies a specific product. That code will allow me to search for the same product in the other file. In my program I have to add the other "variables" from one file to the other, and then replace it, in the same place in one of those files.
I didn't open any of those files with a or a+, I did it with r and r+ because i want to replace the information in the lines that may be in the middle of the file, and not in the end of it.
The program compiles, and runs, but when it comes to replace the info in the file, it just doesn't do anything.
How should I resolve the problem?
A program can replace (overwrite) text in the middle of the file. But the question is whether or not this should be performed.
In order to insert larger text or smaller text (and close up the gap), a new text file must be written. This is assuming the file is not fixed width. The fundamental rule is to copy all original text before the insertion to a new file. Write the new text. Finally write the remaining original text. This is a lot of work and will slow down even the simplest programs.
I suggest you design your data layout before you go any further. Also consider using a database, see my post: At what point is it worth using a database?
Your objective is to design the data to minimize duplication and data fetching.

Resources