Reputation: 51
I am very new to File Handling in C. I would like to ask if there is any way that I could detect if there is an existing data on a file. Because if there's none, I will use "wb"
, but if there is a data already, I will just use append "ab"
.
I tried using "wb"
instead of "ab"
when I write data, but the first data I wrote won't read.
Here is an example:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct clientInfo{
char Name[30];
};
void inputAccounts();
void viewAllRecords();
int main()
{
showOptions();
}
void inputData()
{
FILE *fp;
fp = fopen("hello", "ab");
struct clientInfo PERSONAL;
if(fp == NULL)
{
printf("Error!!!");
getch();
}
else
{
fflush(stdin);
printf("Enter Name: ");
gets(PERSONAL.Name);
fwrite((char *)&PERSONAL, sizeof(struct clientInfo), 1, fp);
printf("File Created!!!");
getch();
fclose(fp);
}
}
void showOptions()
{
char choice;
system("cls");
printf("\n[1] Add Accounts");
printf("\n[2] View Records");
choice = getch();
if (choice == '1')
{
inputData();
}
else if (choice == '2')
{
viewAllRecords();
}
showOptions();
}
void viewAllRecords()
{
FILE *fp;
fp = fopen("hello", "rb");
struct clientInfo PERSONAL;
fread((char *)&PERSONAL, sizeof(struct clientInfo), 1, fp);
system("cls");
if(fp == NULL){
printf("Error!!!");
getch();
}
else
{
while((fread((char *)&PERSONAL, sizeof(struct clientInfo), 1, fp))==1)
{
printf("Name: %s\n", PERSONAL.Name);
}
}
getchar();
}
Upvotes: 1
Views: 1225
Reputation: 44274
Simply use ab
both all cases.
If the file exists already, it will open the file and writing starts from the end of the file.
If the doesn't exists, it will be created and writing starts from the end of the file which is the same as the beginning.
From http://man7.org/linux/man-pages/man3/fopen.3.html:
a Open for appending (writing at end of file). The file is
created if it does not exist. The stream is positioned at the
end of the file.
EDIT
Since OP has posted more code it can be seen that the first entry will never be printed:
struct clientInfo PERSONAL;
fread((char *)&PERSONAL, sizeof(struct clientInfo), 1, fp);
^^^^^^^
Read but there is no print
system("cls");
if(fp == NULL){
printf("Error!!!");
getch();
}
else
{
while((fread((char *)&PERSONAL, sizeof(struct clientInfo), 1, fp))==1)
{
printf("Name: %s\n", PERSONAL.Name);
}
}
the solution is simple - just remove that fread
so that fread
is only done in the while
loop.
Other tips:
For gets
see Why is the gets function so dangerous that it should not be used?
For fflush(stdin);
see Using fflush(stdin)
Upvotes: 1
Reputation: 84551
The standard library also provides the stat
and fstat
functions that allow you to fill a struct stat
to determine the file size directly. stat
takes a file-path and a pointer to a stuct stat
(declared with automatic storage is fine), while fstat
takes an integer file-descriptor as its argument.
Using stat
to determine whether the file size is greater than zero, is a simple matter of calling stat
and then checking the .st_size
struct member.
With appropriate validation, you could do:
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#define MAXC 1024
int main (void) {
char fn[MAXC]; /* filename */
struct stat sbuf; /* stat buffer */
FILE *fp;
/* prompt, read filename, trim line-end */
fputs ("enter filename: ", stdout);
if (!fgets (fn, MAXC, stdin)) {
fputs ("(user canceled input)\n", stderr);
return 1;
}
fn[strcspn (fn, "\r\n")] = 0;
/* call stat, fill stat buffer, validate success */
if (stat (fn, &sbuf) == -1) {
perror ("error-stat");
return 1;
}
/* test sbuf.st_size to check if file size > 0 */
if (sbuf.st_size > 0) {
puts ("opened ab");
fp = fopen (fn, "ab");
}
else {
puts ("opened wb");
fp = fopen (fn, "wb");
}
/* rest of code... */
}
Either way, using seek
or stat
, you can determine what you need.
Upvotes: 1
Reputation: 158
You can use fseek()
to make your purpose done. fseek()
is used to move file pointer associated with a given file to a specific position.
FILE *fp;
fp = fopen("test.txt", "r");
// Moving pointer to end
fseek(fp, 0, SEEK_END);
if(ftell(fp)>0){
printf("data exists on the file.\n");
}else{
printf("no data.\n");
}
for more details you can read this article.
Upvotes: 2