0

The following program creates a new dat file and stores random data. Then one of the values is searched from the file and printed.

The problem is data up to 13 items are searched and the program exits. As shown in following picture 100 inputs are stored and only 13 items are searched. What is the solution?

//  database for storing random values in file and making search operation

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

typedef struct {
    int rollNo;
    int regdNo;
    int salary;
    int status;
} record;

int main(void) {
    int i, n;
    record det;
    int recordsize = sizeof(det);     // size of record

    FILE *fp1 = fopen("random.dat", "a+");
    if (fp1 == NULL) {
        printf("error in opening file : \n");
        return 1;
    }

    printf("enter the no of data to be stored\n");
    scanf("%d", &n);

    for (i = 0; i < n; i++) {
        det.rollNo = rand();
        det.regdNo = rand();
        det.salary = rand();
        det.status = (rand() % 10) + 1;

        fwrite(&det, recordsize, 1, fp1);
    }

    printf("The last roll no of student stored in list: %d\n", det.rollNo);

    int stat = 0, countNumber = 0;
    record buffer;
    int number;

    printf("enter the roll number to be searched\n");
    scanf("%d", &number);

    fseek(fp1, 0, SEEK_SET);  // move file position indicator to beginning of file
    do {
        countNumber++;        // counts number of times the file is searched
        fread(&buffer, recordsize, 1, fp1);
        if (buffer.rollNo == number) {
            stat = 1;
            break;
        }
    } while (!feof(fp1));

    printf("\n");
    if (stat) {
        printf("succesfully found at %d\n", countNumber);
        printf("    roll number %d\n   regd number %d\n   salary %d\n   status %d\n",
               buffer.rollNo, buffer.regdNo, buffer.salary, buffer.status);
    } else
        printf("there is no such roll number %d in the list\nlength of list : %d\n",
               number, countNumber);

    fclose(fp1);
}

The output is:

enter image description here

chqrlie
  • 131,814
  • 10
  • 121
  • 189
Ashish
  • 33
  • 7

2 Answers2

1

Your main problem is that your store binary data where system expect you to store text, see this question.

  • fopen(..., "a+"); open a file for text reading, but you store binary data in it

You have some other issues:

  • You don't use feof the right way
  • Your main function does not return value,
  • You do not test the value of n or number.

Corrected code should looks like:

//  database for storing random values in file and making search operation

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

typedef struct
{
    int rollNo;
    int regdNo;
    int salary;
    int status;
} record;

int main(void) {
    int i, n;
    record det;

    /* open the file in BINARY mode */
    FILE* fp1 = fopen("random.dat" , "a+b");
    if (fp1 == NULL) {
        printf("error in opening file : \n");
        return 1;
    }

    printf("enter the no of data to be stored\n");
    scanf("%d", &n);

    for (i = 0; i < n; i++) {
        det.rollNo = rand();
        det.regdNo = rand();
        det.salary = rand();
        det.status = (rand() % 10) + 1;

        if (1 != fwrite(&det, sizeof det, 1, fp1)) {
            perror("fwrite");
            return 2;
        }
    }

    printf("The last roll no of student stored in list: %d\n", det.rollNo);

    int stat = 0, countNumber = 0;
    record buffer;
    int number;

    printf("enter the roll number to be searched\n");
    scanf("%d", &number);

    fseek(fp1, 0, SEEK_SET); // rewind would have done the job

    while (1) {
        countNumber++;        // counts number of times the file is searched
        if (1 != fread(&buffer, sizeof buffer, 1, fp1)) {
            perror("fread");
            return 3;              
        }
        if (buffer.rollNo == number) {
            stat = 1;
            break;
        }
    }
    printf("\n");
    if (stat) {
        printf("succesfully found at %d\n", countNumber);
        printf("    roll number %d\n   regd number %d\n   salary %d\n   status %d\n", buffer.rollNo, buffer.regdNo, buffer.salary, buffer.status);
    }
    else
        printf("there is no such roll number %d in the list\nlength of list : %d\n", number, countNumber);


    /* warning: file is not closed in case of error... */
    fclose(fp1);

    return 0;
}
Community
  • 1
  • 1
Mathieu
  • 8,840
  • 7
  • 32
  • 45
1

The code works fine on my system, but there are possible problems:

  • you open the binary file in default mode, possibly text mode. Use "ab+" instead.

  • the file is open in append mode. If it contains invalid data, especially if its size is not a multiple of the size of the record size, appended records will not be properly aligned, and thus will not be read back correctly.

  • test the success of the scanf(), fwrite() and fread() calls

  • the end of file test is incorrect.

Here is an improved version:

//  database for storing random values in file and making search operation

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

typedef struct {
    int rollNo;
    int regdNo;
    int salary;
    int status;
} record;

int main(void) {
    int i, n;
    record det;
    int recordsize = sizeof(det);     // size of record

    FILE *fp1 = fopen("random.dat", "ab+");
    if (fp1 == NULL) {
        printf("error in opening file : \n");
        return 1;
    }

    printf("enter the no of data to be stored\n");
    if (scanf("%d", &n) != 1)
        return 1;

    for (i = 0; i < n; i++) {
        det.rollNo = rand();
        det.regdNo = rand();
        det.salary = rand();
        det.status = (rand() % 10) + 1;

        if (fwrite(&det, recordsize, 1, fp1) != 1) {
            perror("cannot write record");
            fclose(fp1);
            return 2;
        }
    }

    printf("The last roll no of student stored in list: %d\n", det.rollNo);

    int stat = 0, countNumber = 0;
    record buffer;
    int number;

    printf("enter the roll number to be searched\n");
    if (scanf("%d", &number) != 1)
        return 1;

    fseek(fp1, 0, SEEK_SET);   // move file position indicator to beginning of file
    while (fread(&buffer, recordsize, 1, fp1) == 1) {
        countNumber++;        // counts number of times the file is searched
        if (buffer.rollNo == number) {
            stat = 1;
            break;
        }
    }

    printf("\n");
    if (stat) {
        printf("successfully found at %d\n", countNumber);
        printf("   roll number %d\n"
               "   regd number %d\n"
               "   salary %d\n"
               "   status %d\n",
               buffer.rollNo, buffer.regdNo, buffer.salary, buffer.status);
    } else {
        printf("there is no such roll number %d in the list\n"
               "length of list : %d\n",
               number, countNumber);
    }
    fclose(fp1);
    return 0;
}
chqrlie
  • 131,814
  • 10
  • 121
  • 189