In C,I cannot update when I close program database - c

I made file that I want to update with the value when the program ends, then read the value from that file again next time the program runs.
For example: In this program I want to subtract an entered value from the saved one. So first I enter 3 then it gives 12. When I run the program again and enter 2, then it gives 13, but it should give 10 rather than 13.
#include<stdio.h>
#define PATH "/tmp/file"
int main()
{
FILE *file;
int age=15,s;
scanf("%d",&s);
file = fopen(PATH, "w");
age = age - s;
fprintf(file, "%d", age);
fclose(file);
file = fopen(PATH,"r");
if (file == NULL)
{
printf("files does not exist");
}
fscanf(file,"%d",&age);
printf("%d",age);
fclose(file);
}

The problem is that you always initialize age to 15, not to what's in your file. Then you write that age to the file, and immediately read it back.
If I understand you correctly, you want to read the file first (not overwrite it), then do your calculation, and write the result back.
#include<stdio.h>
#define PATH "/tmp/file"
int main()
{
FILE *file;
int age = 15, s;
file = fopen(PATH, "r");
if (file == NULL)
{
printf("files does not exist");
return 1;
}
fscanf(file, "%d", &age);
fclose(file);
scanf("%d", &s);
file = fopen(PATH, "w");
age = age - s;
fprintf(file, "%d", age);
fclose(file);
printf("%d", age);
}
Note that you should also do error handling for writing, not only for reading. Writing can fail if the file system is full, or if you don't have write permissions.
Your error handling isn't complete, though: in your code you print an error message, but still keep going. Accessing an invalid file pointer (i.e., NULL) will crash your program with a segmentation fault. I've added a return statement, but you could also put the rest of the logic in an else block.

Related

File Pointer Not Being Assigned a Value When Using fopen()

I am trying to write a simple C program which will read data from a csv file and perform some calculations on this data.
Unfortunately I have a problem where a file pointer of mine, fptr , is not being assigned a value after calling fopen(). I know this is the case after stepping through VS 2017's debugger. Yet I do not know why this is the case. This is a huge problem and means my program will throw some very nasty exceptions any time I try to read data from the file or close the file.
My code is below:
main.c
#include<stdio.h>
#include <stdlib.h> // For exit() function
#include"constants.h" //For access to all project constants
/***************************************************************************************************************
To keep the terminal from automatically closing
Only useful for debugging/testing purposes
***************************************************************************************************************/
void preventTerminalClosure() {
//flushes the standard input
//(clears the input buffer)
while ((getchar()) != '\n');
printf("\n\nPress the ENTER key to close the terminal...\n");
getchar();
}
/***************************************************************************************************************
Read the given input file
***************************************************************************************************************/
void readInputFile(char fileName[]) {
FILE *fptr;
char output[255];
//open the file
if (fptr = fopen(fileName, "r") != NULL) { //read file if file exists
//fscanf(fptr, "%[^\n]", output);
//printf("Data from the file:\n%s", output);
printf("<--Here-->");
}else {
printf("\nERROR 1: File %s not found\n", fileName);
preventTerminalClosure();
exit(1);
}
fclose(fptr); //close the file
}
/***************************************************************************************************************
* * * Main * * *
***************************************************************************************************************/
void main() {
char testName[MAX_NAME_SIZE];
printf("Hello World!\n");
printf("Please enter your name: ");
scanf("%s", testName);
printf("It's nice to meet you %s!", testName);
readInputFile("dummy.txt");
preventTerminalClosure(); //Debug only
}
I have made sure that my fake file does indeed exist and is located in the correct location. Otherwise my code would hit the else block inside of readInputFile(). That is something I have thoroughly tested.
There is clearly something basic that I am missing which explains this pointer behavior; but what that is, I am not sure. Any help would be appreciated! :)
Use parenthesis to enforce order, so that fptr is compared against NULL after it has been assigned value returned by fopen:
FILE *fptr;
char output[255];
//open the file
if ( (fptr = fopen(fileName, "r")) != NULL)

Reading hexadecimal from file

I'm trying to read two records form a file, where one is hexadecimal formated number. Well I'm newcomer to C, before when I been reading hexadecimal, generated by ftok(), I just used printf("%x", key) and it worked fine. Now when I try to read it from the file, it does not work that way.
So my code looks like this:
int countRecords(FILE *f_p) {
int tmp_key = 0;
int tmp_msgqid = 0;
int n = 0;
while (!feof(f_p)) {
if (fscanf(f_p, "%x %i", &tmp_key, &tmp_msgqid) != 2)
break;
n = n + 1;
}
return n;
}
Later on i read this value in the code like:
printf("Records: %i \n", countRecords(f_msgList));
And this compiles with no warnings. Anyway when I run the program the value of countRecords(f_msgList) is 0, when the file have a bunch of data in it:
5a0203ff 360448
850203ff 393217
110203ff 425986
EDIT:
Here is the code where the file is opened or created:
FILE *f_msgList;
f_msgList = fopen("../message_queues.list", "a");
// if file does not exist then create one and check for errors
if (f_msgList == NULL) {
FILE *f_tmp;
f_tmp = fopen("../message_queues.list", "w");
if (f_msgList == NULL) {
fprintf(stderr, "Error occurred while creating the file! \n");
exit(1);
} else
f_msgList = f_tmp;
}
Problems
You opened the file in "append" mode. which does not let you read through the file.
If you want to write and then read the file, file pointer must be reset to the starting of the file.
feof(f_p) is worst way of checking whether file pointer is at end of the file.
Solution
Open File in "read" mode by 'r' or in append+read mode 'a+'.
if you are writing in to the file. reset it using rewind(f_p); after writing.
check out this way to read through the file :
int ret, ans, key;
while ((ret = fscanf(fp, "%x %i", &key, &ans))) {
if (ret == EOF)
break;
else
printf("%x %i \n",key, ans);
}
here integer ret is :
EOF, if the pointer is reached end of file.
0, if no input matched with the variable
(greater than 0), that is, number of matched variables with the file input

Why ftell prints -1 as value of file pointer? And why errno prints out "INVALID ARGUMENT"?

I have these 2 functions in a project which loads and saves user's information into a file. Each user is saved in a new line of the file. My problem is that the program crashes when I try to use ftell(f). When I print ftell(f) it prints -1 after opening the file with fopen(). I tried to see in errno the error, but it prints "NO ERROR" after fopen() but "INVALID ARGUMENT" once I use fseek to modify the file pointer f position.
My problem is in my Load_File function, but I show the Save_File function too for checking I write correctly in the file.
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
LIST Load_File(LIST L){
//PRE: receive a void list (L==NULL)
//POST: returns an user's loaded from file
USER user; //node of list
char str[150];
//User's structure
char name[30];
char CI[10];
char email[30];
char city[30];
char password[30];
errno=0;
FILE *f;
if(f=fopen("DATOS.txt","r")==NULL){
printf("File not found. \n");
return L;
}
//Code for verify what's happening
printf("FTELL: %d/n", ftell(f)); //prints -1
printf("ERRNO: %s\n", strerror(errno)); //prints NO ERROR
fseek(f, 0, SEEK_CUR);
printf("FTELL: %d\n", ftell(f)); //still prints -1
printf("ERRNO: %s\n", strerror(errno)); //prints INVALID ARGUMENT
printf("FEOF: %d\n",feof(f)); //CRASHES! (a)
while(feof(f)==0){ //CRASHES when (a) line is deleted
//Load line of file in user's structure
fgets(str, 150, f);
sscanf(str,"%s %s %s %s %s ",name, CI, email, city, password);
//Copy into structure's parts
strcpy(user->name, name);
strcpy(user->CI, CI);
strcpy(user->email, email);
strcpy(user->city, city);
strcpy(user->password, password);
Add_user_to_list(L, user);
}
if(fclose(f)!=0) printf("\n\n FILE NOT PROPERLY ClOSED \n\n");
}
void Save_File(LIST L){
//PRE: receive an user's list
//POST: saves a new list in file
FILE *f;
int flag=0;
f=fopen("DATOS.txt","w");
if(f==NULL){
printf("Error opening file f\n");
}
if(!L_Void(L)){
L=L_First(L);
do{
if(flag) L=L_Next(L);
flag=1;
fprintf(f,"%s %s %s %s %s \n",L_InfoM(L)->name,L_InfoM(L)->CI, L_InfoM(L)->email, L_InfoM(L)->city, L_InfoM(L)->password);
}while(!L_Final(L));
}else printf("List is void, then nothing was saved.\n");
if(fclose(f)!=0) printf("\n\n FILE NOT PROPERLY COSED \n\n");
}
This code is wrong:
if(f=fopen("DATOS.txt","r")==NULL){
Binary operators - such as == - have higher precedence than assignment operators - such a =.
So your code is parsed as:
if(f=( fopen("DATOS.txt","r")==NULL ) ){
The result of the logical == comparison is assigned to f.
Why are you stuffing the assignment into the if statement? This is much clearer, as well as being a lot less bug-prone:
FILE *f = fopen( "DATOS.txt", "r" );
if ( NULL == f ) {
...
The more you do on one line, the more likely you'll make a mistake. Programming correctly is hard enough. Don't do things that make it harder - like try to see how much code you can stuff into one line.

Reading from file in C Error

I am trying to read values from a file line by line and print them.. and the output is that it prints the last line twice.. Why would it do this being that the last line is the end of the file?
int main(int argc, char* argv[]) {
FILE *file = fopen(argv[1], "r");
if (file == NULL){
printf("error\n");
return 1;
}
unsigned long long address;
int rv = fscanf(file, "%lli", &address);
printf("%lli\n", address);
do{
rv = fscanf(file, "%lli", &address);
printf("%lli\n", address);
} while (rv!=EOF);
fclose(file);
return 0;
}
You don't check if the "inside" fscanf actually succeeded. If you're at the end of the file, it WON'T read anything, &address doesn't get updated, and rv gets 0 for bytes read.
Then you unconditionally print out whatever's in address, which happens to be whatever you did successfully read last - the last line.
Don't use a do/while, use a while()
while((rv = fscan(...)) != EOF) {
printf(...);
}
That way, if fscanf fails, the printf is simply NOT executed.
do/while is basically "do the following at least once", while a while is "do the following zero-or-more times".

Read a file in c on mac desktop 11db error

I'm a student learning C for the first time. I typed in an example the professor gave the class, which is supposed to read in some integers from a file called "input.txt".
Here's the code:
#include <stdio.h>
int main() {
FILE *ifp;
int num = -1, sum = 0;
ifp = fopen("input.txt", "r");
while (num!= 0) {
fscanf(ifp, "%d", &num);
sum +=num;
}
fclose(ifp);
printf("The sum is %d.\n", sum);
return 0;
}
I'm trying to get this program to print out the "sum" like it should, but when I run it, there are no errors yet the only output I get is (11db).
I created a file called "input.txt" and saved it to the desktop, but it's not working.
The file "input.txt" contains:
1
2
3
4
5
I don't know if I'm supposed to somehow, somewhere, define the file path or where/how to do this.
Any help is much appreciated.
Thanks!
My guess would be that the error is because opening the file fails. You should check that fopen returns non-NULL. Opening a file is an operation that often fails. For example:
ifp = fopen("input.txt", "r");
if (ifp == NULL) {
fprintf(stderr, "Couldn't open the file for reading.\n");
}
Unless given a full path name starting with a "/", fopen opens files in the current working directory of the process, and that is probably not the desktop.
Also, when you reach the end of the file, fscanf will return the value EOF. The variable num will not be set to zero. This is a way to read a file of integers:
while (fscanf(ifp, "%d", &num) == 1) {
sum += num;
}

Resources