-1

. Hallo everyone, i'm new in here and also new in c (3 months).

I tryed to make a db in C and the program works fine but i have an issue when i remove the db file (database.txt), i get Segmentation fault (core dumped)

The program is:

#include<stdio.h>
#include<string.h>

#define KRED  "\x1B[31m"
#define KYEL  "\x1B[33m"
#define RESET "\033[0m"
#define TRUE 1
#define FALSE 0

struct{
    int born;
    char firstName[20];
    char lastName[20];
    double phoneNumber;
    int record;
}dataBase;

void showRecord(void);
void noRecord(char record[]);
void searchString(FILE *file, char string[]);

int main(void){
    char name[20];
    const char *db = "database.txt";
    FILE *file = fopen(db, "r");
    dataBase.record=1;

    printf("Please type First or Last name to search:\t");
    scanf("%s", name);

    searchString(file, name);
    fclose(file);
   return 0;
}

void showRecord(void){
    printf("\n\t\tRecord\t%d\n",dataBase.record++);
    printf("First Name:\t%s\n", dataBase.firstName);
    printf("Last Name:\t%s\n", dataBase.lastName);
    printf("Born:\t\t%d\n", dataBase.born);
    printf("Phone Number:\t%.0f\n", dataBase.phoneNumber);
    printf("------------------------------\n");
}

void noRecord(char record[]){
    printf(KRED "\n\t\t\tNo record found with name\t"RESET KYEL "%s\n"RESET , record);
}

void searchString(FILE *file, char string[]){
    int check = 0;

    while(!feof(file)){
      fscanf(file,"\n%s\t%s\t%d\t%lf\t",dataBase.firstName,dataBase.lastName,&dataBase.born,&dataBase.phoneNumber);

        if(strcasecmp(dataBase.firstName,string)==0){
             showRecord();
             check = TRUE;
        }else if(strcasecmp(dataBase.lastName,string)==0){
             showRecord();
             check = TRUE;
        }
    }
    if(check == FALSE) {
        noRecord(string);
    }
}

The db file(database.txt) is:

john doe 1880 1234567

mike michael 1850 7654321

george hartman 1971 2345678

david russo 1982 8765432

michael jackson 1960 3456789

. When i run it looks like this: 1

Please type First or Last name to search:   michael

        Record  1
First Name: mike
Last Name:  michael
Born:       1850
Phone Number:   7654321
------------------------------

        Record  2
First Name: michael
Last Name:  jackson
Born:       1960
Phone Number:   3456789
------------------------------

2

Please type First or Last name to search:   jack

            No record found with name   jack

But if i delete the file, i get:

Segmentation fault (core dumped)

In my opinion i think that i have to make a check to see if the file exist, if the file not exist to print the error. Something like this:

if(file == NULL){
    printf("\n\n\t\t\tOOPS, Fisierul nu exista\n\n");
    break;
}else{
while(!feof(file)){
  fscanf(file,"\n%s\t%s\t%d\t%lf\t",dataBase.firstName,dataBase.lastName,&dataBase.born,&dataBase.phoneNumber);

    if(strcasecmp(dataBase.firstName,string)==0){
         showRecord();
         check = TRUE;
    }else if(strcasecmp(dataBase.lastName,string)==0){
         showRecord();
         check = TRUE;
    }
}

But i don't know how. Thank You all

Michi
  • 5,175
  • 7
  • 33
  • 58

2 Answers2

2

If fopen fails, exit the program.
fscanf will return the number of successfully scanned items. Continue reading the file as long a four items are read.
In the scanf format %19s will prevent overwriting the buffers.

#include<stdio.h>
#include<string.h>

#define KRED  "\x1B[31m"
#define KYEL  "\x1B[33m"
#define RESET "\033[0m"
#define TRUE 1
#define FALSE 0

struct{
    int born;
    char firstName[20];
    char lastName[20];
    double phoneNumber;
    int record;
}dataBase;

void showRecord(){
    printf("\n\t\tRecord\t%d\n",dataBase.record++);
    printf("First Name:\t%s\n", dataBase.firstName);
    printf("Last Name:\t%s\n", dataBase.lastName);
    printf("Born:\t\t%d\n", dataBase.born);
    printf("Phone Number:\t%.0f\n", dataBase.phoneNumber);
    printf("------------------------------\n");
}

void noRecord(char record[]){
    printf(KRED "\n\t\t\tNo record found with name\t"RESET KYEL "%s\n"RESET , record);
}

void searchString(FILE *file, char string[]){
    int check = 0;

    while( ( fscanf(file," %19s %19s %d %lf",dataBase.firstName,dataBase.lastName,&dataBase.born,&dataBase.phoneNumber)) == 4) {
        //read from file as long as fscanf return four successfully scanned items
        if(strcasecmp(dataBase.firstName,string)==0){
             showRecord();
             check = TRUE;
        }else if(strcasecmp(dataBase.lastName,string)==0){
             showRecord();
             check = TRUE;
        }
    }
    if(check == FALSE) {
        noRecord(string);
    }
}

int main(){
    char name[20];
    char *db = "database.txt";
    FILE *file;
    if ( ( file = fopen(db, "r")) == NULL) {
        printf ( "%s does not exist\nCreate it and try again\n", db);
        return 1; //exit the program
    }
    dataBase.record=1;

    printf("Please type First or Last name to search:\t");
    scanf("%19s", name);

    searchString(file, name);
    fclose(file);
   return 0;
}
user3121023
  • 8,181
  • 5
  • 18
  • 16
0

I would check if file exists:

int main(){
    char name[20];
    char *db = "database.txt";

    if ((FILE *file = fopen(db, "r")) == NULL)
    {
        printf ("Error\n");
    }

    dataBase.record=1;

    printf("Please type First or Last name to search:\t");
    scanf("%s", name);

    searchString(file, name);
    fclose(file);
   return 0;
}

And i would also advise you to have a look at this (like mention in the comments of your question): Why is “while ( !feof (file) )” always wrong?

EDIT:

I did some improvements to your code, but I did NOT test it.

#include<stdio.h>
#include<string.h>

#define KRED  "\x1B[31m"
#define KYEL  "\x1B[33m"
#define RESET "\033[0m"
#define TRUE 1
#define FALSE 0

struct
{
  int born;
  char firstName[20];
  char lastName[20];
  double phoneNumber;
  int record;
} dataBase;

void showRecord()
{
  printf("\n\t\tRecord\t%d\n",dataBase.record++);
  printf("First Name:\t%s\n", dataBase.firstName);
  printf("Last Name:\t%s\n", dataBase.lastName);
  printf("Born:\t\t%d\n", dataBase.born);
  printf("Phone Number:\t%.0f\n", dataBase.phoneNumber);
  printf("------------------------------\n");
}

void noRecord(char record[])
{
    printf(KRED "\n\t\t\tNo record found with name\t"RESET KYEL "%s\n"RESET , record);
}

void searchString(FILE *file, char *filename){
  int check = 0;

  // You need the filename to newly open the file!
  if ((FILE *checkFile = fopen(filename,"r")) == NULL)
  {
    printf("\n\n\t\t\tOOPS, the File doesn't exist\n\n");

    // Close the file, we don't need it any more.
    fclose (checkFile);

    // EXIT the programm on error
    exit (1);
  }
  else
  {
    // close the file, we don't need it any more.
    fclose (checkFile);
    // You still need to get rid of while(!feof(file))
    while (!feof(file) && !ferror(file)) 
    {
      fscanf(file,"\n%s\t%s\t%d\t%lf\t",dataBase.firstName,dataBase.lastName,&dataBase.born,&dataBase.phoneNumber);

      if (strcasecmp(dataBase.firstName,string)==0)
      {
        showRecord();
        check = TRUE;
      }
      else if (strcasecmp(dataBase.lastName,string)==0)
      {
        showRecord();
        check = TRUE;
      }
    }
  }

  if(check == FALSE)
  {
    noRecord(string);
  }
}

int main(){
    char name[20];
    char *db = "database.txt";

    // Check if file exists on first open!
    if ((FILE *file = fopen(db, "r")) == NULL)
    {
      printf("Error: File doesn't exist'");
      exit(1);
    }

    dataBase.record=1;

    printf("Please type First or Last name to search:\t");
    scanf("%s", name);

    searchString(file, name);
    fclose(file);
   return 0;
}
Community
  • 1
  • 1
Gerald Zehetner
  • 596
  • 4
  • 21
  • Would you mind updateing the code in your question, I really can't read code posted in comments. – Gerald Zehetner Apr 03 '15 at 11:22
  • in the last post i puted a link with the whole program. ==>>> [CLICK HERE](http://pastebin.com/raw.php?i=8YSxqUNC) – Michi Apr 03 '15 at 11:28
  • As this question should help other users in the future too, it would be useful to update the question (use the "edit" link below the question). Your pastebin could be removed by the time someone else is reading this in the future. – Gerald Zehetner Apr 03 '15 at 11:42
  • why i can not post an code when i do a replay..says all the time that the message is too long? – Michi Apr 03 '15 at 12:04
  • You have to [Edit](http://stackoverflow.com/posts/29429642/edit) your original question! This should work. – Gerald Zehetner Apr 03 '15 at 12:17