#include<stdio.h>
#include<string.h>
void createIndexFile(char[]);
int main()
{
FILE *fp;
char fname[40];
int option;
printf("\nEnter the filename to open: ");
scanf("%s",fname);
fp=fopen(fname,"r");
if(fp==NULL)
{
printf("\nCannot open the file\n");
return 0;
}
else
{
printf("\n%s",fname);
createIndexFile(fname);
}
while(1)
{
printf("\n*****MENU*****\n");
printf("\n1.Display ......\n2.Insert new data\n3.Find data\n4.Display data\n5.Exit\n");
printf("\nChoose an operation: ");
scanf("%d",&option);
switch(option)
{
case 1: break;
case 2: break;
case 3: break;
case 4: break;
case 5: return 0;
default: printf("\nInvalid selection\n");
}
}
}
void createIndexFile(char fname[])
{
int i=0;
char tempFile[40];
char indexFile[40];
printf("\n%s",fname);
strcpy(indexFile,"xyz");
strcpy(tempFile,fname);
while(tempFile[i]!='.')
{
if(tempFile[i]=='/')
tempFile[i]='_';
}
strcat(tempFile,".idx");
strcat(indexFile,tempFile);
printf("\nIndex File Name: %s",indexFile);
}
It is a program where after a filename is entered suppose /home/abc.txt and my name is xyz then an index file should be created xyz_home_abc.idx.
After the filename is entered and if it is present, it should go to else part and function
createIndexFile(fname);
should be called. But inside the function, nothing is working properly. If we print a character or something, it is printed. But if I try to give another printf it is not working.
Corrected your function
void createIndexFile(char fname[])
{
int i=0;
char tempFile[40];
char indexFile[40];
printf("\n%s",fname);
strcpy(indexFile,"");
while(fname[i]!='.')
{
if(fname[i]=='/')
tempFile[i]='_';
else
tempFile[i]=fname[i];
i++;
}
tempFile[i]='\0';
strcat(tempFile,".idx");
strcat(indexFile,tempFile);
printf("\nIndex File Name: %s",indexFile);
}
Related
I have a file student.txt and it has a content like
Name RollNo Address ...\n
Name RollNo Address ...\n
And I have written a function to search a Name in the file
it's menu driven and goes like
std student;
FILE *file = NULL;
int choice;
char name[20];
while (1)
{
printf("Enter the choice\n1.Insert\t2.Append\t3.Search\t4.Display: ");
scanf("%d", &choice);
switch (choice)
{
case 1:
//insertion
break;
case 2:
// append
break;
case 3:
printf("Enter the student name to be searched: ");
scanf("%d", &name);
search(name, &file);
break;
case 4:
// display
break;
default:
exit(0);
break;
}
}
return 0;
search function is
void search(char ele[], FILE **fileptr)
{
*fileptr = freopen("student.txt", "r", *fileptr);
char line[100];
while (fgets(line, 100, *fileptr) != NULL)
{
if (strstr(line, ele) != NULL)
{
getchar();
printf("Congrats !!\n");
return;
}
}
printf("not found\n");
fclose(*fileptr);
}
But when i run this though has a filename matching filename it goes to an infinite loop and executes display function and triggers search function itself infinitely
It happens when the data is not taken in correctly using a correct format specifier.
In case 3, in the scanf function, use the format specifier
%s
instead of
%d
That will stop the infinite loop.
This code read/write data to/from binary file. Here modify() will take input from user, search for it in the file. If found, will prompt user to give new entry and the older entry would be replaced.
The question is, in modify() after fwrite() if I break the while loop then everything would be fine but, if I don't then the entry would still be modified but along with that the content of the file would be duplicated, why so ?
As in the beginning there are no duplicate entries in the file. So what I expect is, that even if I don't use break the loop should go on and finally terminate when whole file has been read. Here, the if(strcmp(e.name,user)==0) would only be true for one entry therefore the control should enter only once in this if block. Then how the entries are getting duplicated ?
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void add(FILE *);
void list(FILE *);
void modify(FILE *);
struct emp
{
char name[20];
int id;
float sal;
}e;
void add(FILE *f)
{
char *p=NULL;
printf("\nEnter name id sal\n");
scanf(" %s %d %f", e.name,&e.id,&e.sal);
fseek(f,0,SEEK_END);
if((fwrite(&e,sizeof(struct emp),1,f))==1)
{
printf("\nAdded Successfully\n");
}
else
{
printf("\nError wrting to file in ADD func\n");
}
}
void list(FILE *f)
{
rewind(f);
while(fread(&e,sizeof(struct emp),1,f)>0)
{
printf("\nRead %s %d %f\n",e.name,e.id,e.sal);
}
}
void modify(FILE *f)
{
char user[20];
char *p=NULL;
printf("\nEnter name to modify\n");
scanf(" %s", user);
rewind(f);
while(fread(&e,sizeof(struct emp),1,f)==1)
{
//printf("\n --------------- %s %d %f\n",e.name,e.id,e.sal);
if(strcmp(e.name,user)==0)
{
//fseek(f,-sizeof(struct emp),SEEK_CUR);
printf("\nEnter new name id salary\n");
scanf(" %s %d %f", e.name,&e.id,&e.sal);
fseek(f,-sizeof(struct emp),SEEK_CUR);
if(fwrite(&e,sizeof(struct emp),1,f)==1)
{
printf("\nModified successfull!!\n");
//break;
}
else
{
printf("\nError while modifying\n");
}
}
else
{
printf("\n\nstring not matched\n\n");
}
}
}
int main()
{
char val='T';
FILE *fp=NULL;
if((fp=fopen("database.dat","rb+"))==NULL)
{
if((fp=fopen("database.dat","wb+"))==NULL)
{
printf("\nError opening file in wb+ mode\n");
exit(0);
}
}
do
{
printf("\nEnter a to add, l to list, d to delete, m to modify and e to exit\n");
scanf(" %c", &val);
switch(val)
{
case 'a':
add(fp);
break;
case 'l':
list(fp);
break;
case 'm':
modify(fp);
break;
case 'd':
// del(fp);
break;
case 'e':
fclose(fp);
exit(0);
break;
default:
printf("\nInvalid Input\n");
break;
}
}
while(1);
}
I think it's a problem between fread() and fwrite().
After you use fwrite() to modify the emp, you continue the while loop without using fseek().
In fact, before, you used fseek() to go back and it was OK.
Now you have to place another fseek() which doesn't move, like this:
fseek(f, 0, SEEK_CUR);
Now you can remove the break and your Modify() function would seems like this:
void modify(FILE *f)
{
char user[20];
printf("\nEnter name to modify\n");
scanf("%s",user);
fflush(stdin);
rewind(f);
while(fread(&e,sizeof(struct emp),1,f)==1)
{
if(strcmp(e.name,user)==0)
{
printf("\nEnter new name id salary\n");
scanf("%s %d %f",e.name,&e.id,&e.sal);
fflush(stdin);
fseek(f,-sizeof(struct emp),SEEK_CUR);
if(fwrite(&e,sizeof(struct emp),1,f)==1)
{
printf("\nModified successfull!!\n");
//break; //This can be removed
fseek(f, 0, SEEK_CUR); //Place this here
}
else
{
printf("\nError while modifying\n");
}
}
else
{
printf("\n\nstring not matched\n\n");
}
}
}
my code is:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
char names[10][31];
int u=0;
char new[31];
int ctr=1;
int notInList=0;
int y=0;
int i=0;
char *p;
strcpy(names[0],"mahmoud");
while(1)
{
printf("\t\t§§§Menu items§§§\n");
printf("1==>enter a new name\n");
printf("2==>search for a name\n");
printf("3==>delete a name from the list\n");
printf("Note !!.. ((if you want to exit the program press(1)and then type ((exit))\n");
fflush(stdin);
scanf("%i",&u);
notInList=1;
if(u==1)
{
printf("please enter a name : ");
fflush(stdin);
gets(new);
_strlwr(new);
if(strcmp(new,"exit")==0)
{
printf("bye bye\n");
break;
}
else
{
notInList=1;
for(int i=0;i<=ctr;i++)
{
p=strstr(new,names[i]);
if(strcmp(new,names[i])==0)
{
printf("the name is already exist\n");
break;
}
else if (p)
{
printf("did you mean (( %s ))\n",names[i]);
printf("1==>yes\n");
printf("2==>no\n");
fflush(stdin);
scanf("%d",&y);
if(y==1)
{
printf("the name is already exist\n");
break;
}
else if(y==2)
{
notInList=0;
strcpy(new,names[ctr]);
ctr++;
break;
}
else printf("plz enter a number from the list");
}
else
{
notInList=0;
}
}
if(notInList==0)
{
strcpy(new,names[ctr]);
ctr++;
for(int i=0;i<ctr;i++);
{
printf("%d==>%s\n",i+1,names[i]);
}
}
// break;
}
}
return 0;
}
the first problem is: when I enter ( 1) and then add a name is similar to the first name it printf to me did you mean ( )//// without a name
the second is when I want to add a new name it doesn't please help me
notice that he program is not finished only the first choise
The 1. and 3. menu items are working, but if I choose the 2. menu item it's not listing my data. Why is that?
(It has to be compiled and run in linux command line [NO IDE!])
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <time.h>
struct log{
int id;
char name[20];
char location[20];
int quantity;
char quantity_type[10];
time_t added;
};
char fname[] = "data2.dat";
void add();
void listAll();
int nextId();
int main(){
int ch;
while(1){
system("clear");
printf("///Log stuff!///\n\n");
printf("1. Add\n");
printf("2. List all\n");
printf("0. Exit\n");
printf("\n///////////////////////////////\n\n");
printf("Choose a number from the menu: ");
scanf("%d", &ch);
switch(ch){
case 1: add();
break;
case 2: listAll();
break;
case 0: exit(0);
break;
}
}
return 0;
}
void add(){
FILE *f;
struct log log;
f = fopen(fname, "ab");
if(f == NULL){perror("Can't open!\n");}
log.id = nextId();
printf("\nName: ");
scanf("%s", log.name);
printf("\nLocation: ");
scanf("%s", log.location);
printf("\nQuantity: ");
scanf("%d", &log.quantity);
printf("\nQuantity type: ");
scanf("%s", log.quantity_type);
log.added = time(NULL);
fwrite(&log,sizeof(log),1,f);
fclose(f);
}
void listAll(){
FILE *f;
struct log log;
f = fopen(fname,"rb");
if(f == NULL){perror("Can't open!\n");exit(1);}
printf("\n///////////////////////////////\n\n");
printf("\tList of all data\n\n");
printf("///////////////////////////////\n\n");
while(fread(&log,sizeof(log),1,f) == 1){
printf("%d\t",log.id);
printf("%s\t",log.name);
printf("%s\t",log.location);
printf("%d\t",log.quantity);
printf("%s\t",log.quantity_type);
printf("%s",ctime(&log.added));
}
printf("\n///////////////////////////////\n\n");
fclose(f);
}
int nextId(){
FILE *f;
struct log log;
int id = 1;
f = fopen(fname, "rb");
if(f == NULL){perror("Can't open!\n");}
while(!feof(f)){
fread(&log, sizeof(log), 1, f);
if(log.id >= id){id = log.id + 1;}
}
fclose(f);
return id;
}
Is there a more elegant way to do this task?
This menu display/input choice/switch section of the code has a logic error
the screen is being cleared before the user has a chance to look at any displayed data.
Proper placement of calls to system(clear) and getchar() will fix the problem
a function should only have 1 normal exit. Any other exit points should be only for error conditions
You might try the following:
system(clear);
int done = 0;
while( !done )
{
printf("///Log stuff!///\n\n");
printf("1. Add\n");
printf("2. List all\n");
printf("3. Exit\n");
printf("\n///////////////////////////////\n\n");
printf("Choose a number from the menu: ");
if( 1 != scanf("%d", &ch) )
{ // then scanf failed
perror( "scanf for menu choice failed" );
exit( EXIT_FAILURE );
}
// implied else, scanf successful
// eliminate menu from screen
system(clear);
switch(ch)
{
case 1:
add();
break;
case 2:
listAll();
printf( "\npress any key to continue\n" );
getchar();
break;
case 3:
done=1;
break;
default:
printf("\nyou entered an invalid menu selection, try again\n");
break;
} // end switch
} // end while
I try to load the contents of a text file into a structure.
My idea looks like this:
I have two files, struct.h , main.c and a list.txt file .
in file struct.h :
struct analg {
char word[6];
char signature[6];
};
struct analg h[106];
FILE *fp;
In file main.c :
#include<stdio.h>
#include "struct.h"
void load() {
fp = fopen("list.txt", "r");
if(fp == NULL) {
printf("fail");
return 1;
}
else {
printf("file loaded!\n");
}
fclose(fp);
return;
}
void print() {
int i;
for(i=0; i<1000; i++) {
while(fgets(h[i].word, 6, fp)) {
printf("%s", h[i].word);
}
}
return;
}
int main () {
int choice;
do {
printf("choose L or P: ");
scanf("%s", &choice);
switch(choice) {
case 'l':
load();
printf("\n[l]oad - [p]rint\n");
break;
case 'p':
print();
printf("\n[l]oad - [p]rint\n");
break;
default:
break;
}
} while(choice!='q');
return;
}
In file list.txt :
throw
timer
tones
tower
trace
trade
tread
So I try to load the text file by pressing the "L" to the structure, and then when I press the 'p' will be displayed, but it is not!
In your code, I see there are 2 potential issues. The choice has to be a character to be switched based on l or p. You may have to add cases to handle the upper case also.
Another issue is that in load function, you are closing the file pointer. Hence, when you enter the print function fgets may not work as the fp is already closed.
To load your file into structure, the load has to be modified as
void load() {
fp = fopen("list.txt", "r");
if(fp == NULL) {
printf("fail");
return; // There was an error in original code as this was returning 1
}
do{
fgets(h[count++].word, 6, fp); // Count is a global variable - no. of elements read
}while(!feof(fp));
printf("file loaded!\n");
fclose(fp);
return;
}
The corresponding print function would become
void print(){
int i;
printf("Inside print\n");
for(i=0; i < count; i++) {
printf("%s", h[i].word);
}
return;
}
the main function would be,
int main (){
char choice;
do{
printf("choose L or P: ");
scanf("%c", &choice); //Only character is read and hence, %s is not required
switch(choice){
case 'l':
load();
printf("\n[l]oad - [p]rint\n");
break;
case 'p':
print();
printf("\n[l]oad - [p]rint\n");
break;
default:
case 'q':
break;
}
} while(choice !='q');
return 0;
}
One last point. In the scanf statement if scanf("%s", &choice); is employed, then a runtime check error is generated when main exits, with a message that stack is corrupted around the variable choice.
I'll comment up what your code is doing:
void load() {
fp = fopen("list.txt", "r"); // opens the file for reading
if(fp == NULL) {
printf("fail"); // if the file couldn't be opened, return an error
return 1; // (aside: a void function can't return an int)
}
else {
printf("file loaded!\n"); // tell the user that the file was opened
}
fclose(fp); // close the file, having read nothing from it
return;
}
At no point do you read anything from the file. What you have in memory will therefore have no relation to whatever you have on disk.
C has no built-in means for serialising and deserialising structs so what you need to do is define a formal grammar for your file on disk and write code that can parse that grammar into your structs.