0

I'm new with C, and on the university they are making us create a program that can save data introduced by the user, read the data and check if it’s well introduced. After that it must save that data in each free space, you have 10 empty spaces for saving the data. With all the data saved it must show also the data and compare it with all the data introduced. I made the part of reading the data introduced and cheking if its ok. The problem that I have is that I don’t know how I could make the data base and show that data. Here is the code that I have till now.

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

    typedef struct {
       char name[30];
       int num_sample;
       char section;
       int cabin;
       int day;
       int month;
       int year;
    }Species;

    int menu() {

        int op = 0;

        printf ("\nPrototype Nature Reserve.\n");
        printf ("1. Insert a new species.\n");
        printf ("2. List the species housed.\n");
        printf ("3. Show stadistics.\n");
        printf ("4. Exit.\n");
        printf ("\nIntroduce an option: ");
        scanf ("%d", &op);

        return op;
    }

    void New_species() {

        Species e;
        int i, j;
        char species[100];
        char aux[10];
        printf("Enter data:\n");
        //A fflush is made to not have a problem with the number entered in the menu
        fflush(stdin);
        gets (species);
        //While it is different from - read the text
        for (i = 0; species[i] != '-'; i++) {
          e.name[i] = species[i];
        }
        e.name[i] = '\0';
        i++;
        //We add 1 to the position i because is ending in - and should start reading from the following
        for (j = 0; species[i] != '-'; i++,j++) {
            aux[j] = species[i];
        }
        aux[j] = '\0';
        e.num_sample = My_atoi(aux);
        // Check that the sample is a number and not a character
        if (e.num_sample <= 0 || e.num_sample >= 100) {
            printf ("--> Error in data format.\n");
        }
        i++;
        //Reads the day introduced
        for (j = 0; species[i] != '/'; i++, j++) {
             aux[j] = species[i];
        }
        aux[j] = '\0';
        e.day = My_atoi(aux);
        //Controls the format of the day
        if (e.day <= 0 || e.day > 31) {
            printf ("--> Error in data format.\n");
        }
        i++;
        //Reads the month introduced
        for (j = 0; species[i] != '/'; i++, j++) {
            aux[j] = species[i];
        }
        aux[j] = '\0';
        e.month = My_atoi(aux);
        //Controls the format of the month
        if (e.month <= 0 || e.month > 12) {
            printf ("--> Error in data format.\n");
        }
        i++;
        //Reads the year introduced
        for (j = 0; species[i] != '-'; i++, j++) {
            aux[j] = species[i];
        }
        aux[j] = '\0';
        e.year = My_atoi(aux);
        //Controls the format of the year
        if (e.year < 1970 || e.year > 2060) {
            printf ("--> Error in data format.\n");
        }
        i++;
        //Reads the section introduced
        e.section = species[i];
        //Controls that the section is in capital letters
        if (e.section < 'A' || e.section > 'Z') {
            printf ("--> Error in data format.\n");
        }
        i+= 2;
        //As the cabin is at the end it must reach the \0
        for (j = 0; species[i] != '\0'; i++, j++) {
            aux[j] = species[i];
        }
        aux[j] = '\0';
        e.cabin = My_atoi(aux);
        if (e.cabin < 0 || e.cabin > 20) {
            printf ("--> Error in data format.\n");
        }
        printf ("Species stored successfully (%d/10 free).");
        //This printf is just to ensure that the data entered was read correctly
        printf ("\n%s", species);
    }

    int My_atoi(char cad[10]) {
        int r = 0;
        int i;
        for (i = 0; cad[i] != '\0'; i++) {
           r = r * 10;
           r += cad[i] - '0';
        }
        return r;
    }

    void list_species() {

    }

    void stadistics() {

    }

    void executeOption(int op) {
       switch (op) {
            case 1:
                New_species();
                break;
            case 2:
                list_species();
                break;
            case 3:
                stadistics();
                break;
            default:
                break;
        }
    }

    int main() {
        int op = 0;
        do {
            op = menu();
            executeOption(op);
        } while (op != 4);
        return 0;
    }

I’ve seen that you can use files* so it can create a .txt file for storing but I don’t know how to use it and I don't think that it's allowed in this program.

I'll leave a photo of how it should work

Thanks.

Herdo
  • 1
  • 1
    `fflush(stdin);` in `void New_species()` may not work as you expect – sjsam Apr 22 '16 at 14:04
  • 1
    If this assignment is not about files, it's probably a matter of defining a global array of 10 `Species` and using it to store and retrieve the data. – Quentin Apr 22 '16 at 14:05
  • 1
    Also `Species e;` you're creating an object that is local to `void New_species()` The object will be cleared when the function stack is cleared. That means `e` is not persistent.. – sjsam Apr 22 '16 at 14:06
  • I think is too broad. To start you should make `Species e;` global and array. `Species e[10]`. Using a global counter you should count inserted species to avoid access to that array out of bound – LPs Apr 22 '16 at 14:08
  • Take a look at: [why-is-the-gets-function-so-dangerous-that-it-should-not-be-used](http://stackoverflow.com/questions/1694036/why-is-the-gets-function-so-dangerous-that-it-should-not-be-used). BTW you are using it wrongly: that function must be use to read C-Strings from an input, in your case stdin. You cannot gets a structure. – LPs Apr 22 '16 at 14:22
  • What book, document or person suggested using `gets (species);`? – chux - Reinstate Monica Apr 22 '16 at 15:06

3 Answers3

0

ok u need to save data to a file and load from a file. here a short code of my and read and write:

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


typedef struct worker
{
int sal;
char name[25];  
}W;


void main()
{

 FILE *f;
 int i,j=4;
 W a[3];

 while(j!=3)
 {
 printf("\nEnter\n[1]write\n[2]read\n[3]exit\n");
 scanf("%d",&j);    
if(j==1)
{
if (f==NULL)
 {
    printf("Error!!\n");
    exit(0);
}   
f=fopen("workers.txt","w");
for(i=0;i<3;i++)
 {
printf("\nEnter worker name:   ");
scanf("%s",&a[i].name); 
printf("\nEnter worker sal:    ");
scanf("%d",&a[i].sal);      
fprintf(f,"%s %d",a[i].name,a[i].sal);  
}       

if(j==2)
{
if (f==NULL)
{
    printf("Error!!\n");
    exit(0);
}   
f=fopen("workers.txt","r");
for(i=0;i<3;i++)
{
 fscanf(f,"%s %d",a[i].name,&a[i].sal);
printf("\n%s %d",a[i].name,a[i].sal);
}   
}   
}

fclose(f);}
dor
  • 23
  • 3
0

and I don't think that it's allowed in this program

why wouldn't you be allowed? Yes indeed you can go through two alternatives

To text file This is the one proposed by dor in his answer where he shows you the way of writing text through fprintf.

To binary file You can also write to a file using fwrite/fseek like this example I found surfing around you can check it out here -> c-tutorial-binary-file-io

#include<stdio.h>

/* Our structure */
struct rec
{
    int x,y,z;
};

int main()
{
    int counter;
    FILE *ptr_myfile;
    struct rec my_record;

    ptr_myfile=fopen("test.bin","wb");
    if (!ptr_myfile)
    {
        printf("Unable to open file!");
        return 1;
    }
    for ( counter=1; counter <= 10; counter++)
    {
        my_record.x= counter;
        fwrite(&my_record, sizeof(struct rec), 1, ptr_myfile);
    }
    fclose(ptr_myfile);
    return 0;
}

and retrieving back the data from the binary may go this way as the tutorial shows

    #include<stdio.h>

/* Our structure */
struct rec
{
    int x,y,z;
};

int main()
{
    int counter;
    FILE *ptr_myfile;
    struct rec my_record;

    ptr_myfile=fopen("test.bin","rb");
    if (!ptr_myfile)
    {
        printf("Unable to open file!");
        return 1;
    }
    for ( counter=1; counter <= 10; counter++)
    {
        fread(&my_record,sizeof(struct rec),1,ptr_myfile);
        printf("%d\n",my_record.x);
    }
    fclose(ptr_myfile);
    return 0;
}
Devarg
  • 73
  • 5
0

If you are looking for a solution in a .txt file I have a proposal,

    #include <stdio.h>
int main(){
    FILE *in;
    FILE *OUT = fopen("read_at.txt", "w");
    char name[20];
    char capture[80];
    int age = 0;
    float grade = 0;

    puts("introduce your name:");
    scanf("%19s", name);
    puts("introduce your age:");
    scanf("%i", &age);
    puts("introduce your Math grade(0-10):");
    scanf("%f", &grade);

    fprintf(OUT, "Age %i, Grade %f, Name %s\r\n", age, grade, name);
    fclose(OUT);
    if(!(in = fopen("read_at.txt","r"))){
        fprintf(stderr, "The file could not be opened. \n");
        return 1;
    }
    while (fscanf(in, "Age %i, Grade %f, Name %20[^\n]\n", &age, &grade, name)==3){
        printf("A %i years old student has achieved a %f mark in last math exam, that student is: %s", age,grade, name);
    }
    fclose(in);
}

In this code that I have just created you can see how you can just create one file and read and get its data if it has a concrete format. If you are looking for a database you can just put values separated by “;” and new lines (\n). With that if you save it as .csv you would obtain an excel sheet and quite a good database. If you are interested in this solution, just let me know if you need any additional help.

Regards,