My C program for making a database which stores data and from which data can be retrieved is stated later.But I am not able to write the function for editing the stored items correctly.Please suggest a method.Also suggest :1.mode in which file is to be opened in case 2 of the switch
2.Due to usage of scanf functions in case 1,strings with whitespaces cannot be entered correctly.Also if scanf("[^\n]",..)or gets(...) are used then problem is: stray '\n' is taken as input for the strings instead of taking any string from the user---please suggest!

#include<stdio.h>
#include <string.h>
#include <conio.h>
#include <stdlib.h>
typedef struct {
char name[30];
char company[50];
char address[200];
char pin[7];
char web[30];
}entry;
char name[30];char company[50]; 
FILE *fpt;int menu(void);
entry *ptr,commodity;
int n=sizeof(entry);char ch,y;
void edit(entry *);
void main()
{
int choice;
do
{
choice=menu();
switch(choice)
{
case 1:ptr=(entry *)malloc(sizeof(entry));
fpt=fopen("data5.bin","a");
printf("\nEnter the name of the commodity:");
scanf("%s",ptr->name);
printf("\nEnter the name of the producing company:");
scanf("%s",ptr->company);
printf("\nEnter the address of the producing company:");
scanf("%s",ptr->address);
printf("\nEnter the pincode:");
scanf("%s",ptr->pin);
printf("\nEnter the website of the producing company:");
scanf("%s",ptr->web);
fwrite(ptr,n,1,fpt);printf("ENTERED\n");
fclose(fpt);
continue;
case 2:ptr=(entry *)malloc(sizeof(entry)); 
fpt=fopen("data5.bin","r+");
do 
{
if (fread(&ptr->name, sizeof(ptr->name), 1, fpt) == 1 &&
fread(&ptr->company, sizeof(ptr->company), 1, fpt) == 1 &&
fread(&ptr->address, sizeof(ptr->address), 1, fpt) == 1 &&
fread(&ptr->pin, sizeof(ptr->pin), 1, fpt) == 1 && 
fread(&ptr->web, sizeof(ptr->web), 1, fpt) == 1)
{
printf("\n\nThe name of the commodity:");
printf("%s",ptr->name);
printf("\nThe name of the producing company:");
printf("%s",ptr->company);
printf("\nThe address of the producing company:");
printf("%s",ptr->address);
printf("\nPincode:");
printf("%s",ptr->pin);
printf("\nWebsite of the producing company:");
printf("%s",ptr->web);
printf("\nWant to EDIT this entry?(Enter y/n):");
ch=getchar();
if(ch==y) 
edit(ptr);
}
else if (feof(fpt)) 
{
printf("\n\nfinished reading file!\n");
break;
}
else {
printf("an error occured while reading the file!\n");
break;
}
} while (1);
fclose(fpt);continue;
case 3:printf("\nThank You for using!");exit(1); 
}
}while(choice==1||choice==2);
getch();
}
int menu(void)
{
int choice;
do{
printf("Enter your choice:\n");
printf("1.ADD a entry\n");
printf("2.DISPLAY cum EDIT\n");
printf("3.EXIT\n");
scanf("%d",&choice);
}while(choice!=1 && choice!=2 && choice!=3);
return(choice);
}
void edit(entry *ptr)
{
printf("\nWant to EDIT name of commodity?(y/n):");
ch=getchar();
if(ch==y)
{ 
printf("\nEnter new commodity name:");
scanf("%s",name);
ptr->name=name;
}
printf("\nWant to EDIT name of company?(y/n):");
ch=getchar();
if(ch==y)
{ 
printf("\nEnter new company name:");
scanf("%s",company);
ptr->company=company;
} //....etc..etc.
fwrite(ptr,n,1,fpt);
return;
}

:?:

1. For upadting "r+" can be used.
2. What should be the last character of ur string or how u want ur string to terminate ?

Editing is a trick in File based databases.........you can use several ways to achieve this....

1. Use the array of Structure and read the entire file in array of structure.......... and do all the work with that array and write the array back to the file........................ its not effecient. as your size increases. You may get some problems.

2. you can use fseek() function..................
here is an example of using fseek to get the desired record.
int fseek(FILE* stream, long offset, int origin)
Now, your structure size is around 317 bytes. now to get nth record you can use
fseek(file_ptr, ((n-1)*sizeof(entry)),SEEK_SET);


Now to update the file you can either use r+, a+ or w+.
if you need a string that are separated by whitespace (i.e. Space) then you should use a string array or char** or array of char*.

"scanf() terminates on \n". I havent seen any example of using \n in scanf() :).
Try to read the entire structure using fread(&entry,sizeof(entry),1,file_ptr);
I think this would help you out........:confused:

:) The prob is that if I want to enter choice#1(for storing new data in the file) ,I press '2' and 'enter' keys.But this '\n' is taken as a input for the name of the commodity and the computer then instantly asks for the name of the company.............suggest a way out to be able to input strings with whitespaces without this problem.
fgets() is also causing the same problem.

you can use fseek() function..................
here is an example of using fseek to get the desired record.
int fseek(FILE* stream, long offset, int origin)
Now, your structure size is around 317 bytes. now to get nth record you can use
fseek(file_ptr, ((n-1)*sizeof(entry)),SEEK_SET);

Will you please be more specific about the use fseek(), I am not much acquainted with it and it can help my prog.

Sorry for late replying! was busy! hmmmZ. sending you a snippet of code that might help you :). concentrate on the technique of reading and writing to file you can Edit any record ~!.Check the technique of Record Number that is included. now Code the delete function yourself :). Hope you get the basic idea :)

#include <cstdio>
struct CData; //declaration
void Add(CData* val);
void Edit(CData* val,int rec_no);
void Read_CData(CData*);
void Print_CData(CData*);
FILE* fp; 
struct CData {
int iRecNo; //holds the record number;
char Cust_Name[20]; //holds the name only 
};
void Init() 
{
if((fp = fopen("c:\\laiq.txt","a+r"))==0)
{
printf("Error");
exit(0);
}
else
printf("File is opened SuccessFully\n");
}
void ShutDown()
{
fclose(fp);
}
void Add(CData* data)
{
//read the data from Console
if(!fp)
Init();

Read_CData(data);
fseek(fp,0,SEEK_END);
fwrite(data,sizeof(*data),1,fp);

}
void Edit(CData* val,int rec_no)
{
fseek(fp,(rec_no-1)*sizeof(*val),SEEK_SET);
fread(val,sizeof(*val),1,fp);
Print_CData(val);
}
int get_Rec(){
static int rec_no;
return rec_no++;
}
void Read_CData(CData* val)
{ 
val->iRecNo=get_Rec();
printf("\nEnter the Customer Name: ");
gets(val->Cust_Name);
}
void Print_CData(CData* val)
{
if(val){
printf("Record Number: %d\n",((val->iRecNo)+1));
printf("Customer Name is: %s",val->Cust_Name);
}
else 
printf("Nothing to print :P");
}
int main()
{
CData value; //value is used for adding records :).
Init();
Add(&value);
Add(&value);
Add(&value);
CData val; //holds the record for editing :)
Edit(&val,2); 
ShutDown();

return 0;
}

still having problem then use the MSDN Library :) for File Pointer

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.