Thread: Datebase of students in C

  1. #1
    Registered User
    Join Date
    Dec 2017
    Posts
    6

    Datebase of students in C

    Hello,
    I'm trying to make a datebase of a students in C.
    Here is my code: [C] C - Pastebin.com
    Now I stuck on add student. I realloc the array memory but i can't add a new student. After read it I want to export to the initial DB.
    I can not figure out what the problem is even I used debugger.
    Someone could help me?

  2. #2
    Registered User rstanley's Avatar
    Join Date
    Jun 2014
    Location
    New York, NY
    Posts
    1,111
    For starters:

    Please post your code in CODE tags!

    main() ALWAYS returns an int! Never, "void main()"

    Please don't cast the return from malloc(), calloc(), and realloc().

    Please also post some sample data so we can test your program.

    Start here, then we can offer further assistance.

  3. #3
    Registered User
    Join Date
    Dec 2017
    Posts
    6
    Firstly, thank you for your reply.

    Here is a sample data to test in a txt file (InitialDB.txt):
    Student1First
    Student1Last
    7
    Student2First
    Student2Last
    10
    And when I'm trying to add a new student I get my program crashed. Also I modified void to int.

  4. #4
    Registered User
    Join Date
    May 2010
    Posts
    4,632
    Here is the code in question:

    Code:
    #include <malloc.h>
    #include <stdio.h>
    #include <malloc.h>
    #include <string.h>
    
    typedef struct StudentDynamic
    {
    	char* firstName;
    	char* lastName;
    	float grade;
    }StudentDynamic;
    
    void exportCSV(char *filename, StudentDynamic* pStudents, int nStudents)
    {
    	printf("\n Creating %s.csv file. \n ", filename);
    	FILE *fp;
    	filename = strcat(filename, ".csv");
    	fp = fopen(filename, "w+");
    	fprintf(fp, "Student No., First Name, Last Name, Grade");
    	for (int i = 0; i<nStudents; ++i)
    	{
    		fprintf(fp, "\n%d", i+1);
    		fprintf(fp, ",%s ", pStudents[i].firstName);
    		fprintf(fp, ",%s ", pStudents[i].lastName);
    		fprintf(fp, ",%f ", pStudents[i].grade);
    	}
    	fclose(fp);
    	printf("\n File %s succesfully created!\n", filename);
    }
    
    void printStudents(StudentDynamic* pStudents, int nStudents)
    {
    	printf("========== List of Students ==========\n");
    	for (int i = 0; i < nStudents; ++i)
    	{
    		printf("%d. %10s %10s %7.2f", i + 1,
    			pStudents[i].firstName,
    			pStudents[i].lastName,
    			pStudents[i].grade);
    		printf("\n");
    	}
    }
    
    int main()
    {
    	int nStudents, i;
    
    	char choice;
    	printf("\t\t================== STUDENT DATABASE APPLICATION ==================");
    	printf("\n\n                                          ");
    	printf("\n\n");
    	printf(" \n\t\t\t============================================");
    	printf("\n \t\t\t  1. Read Students from Default File");
    	printf("\n \t\t\t  2. Create Student");
    	printf("\n \t\t\t  3. Update Record");
    	printf("\n \t\t\t  4. Delete Record");
    	printf("\n \t\t\t  5. Export DB to CSV");
    	printf("\n \t\t\t  6. List Students");
    	printf("\n \t\t\t  7. Exit Program");
    	printf(" \n\t\t\t============================================");
    	printf("\n\n");
    	printf("\t\t\t Select Your Choice : ");
    
    	while (1)
    	{
    		fflush(stdin);
    		choice = getche();
    		printf("\n");
    		switch (choice)
    		{
    		case '1':
    			StudentDynamic* pStudents = NULL;
    			char auxfirstName[100], auxlastName[100];
    			float auxGrade;
    			FILE* pFile = fopen("InitialDB.txt", "r");
    			if (pFile == NULL)
    			{
    				printf("Could not open file or is empty! Exiting...");
    				exit(2);
    			}
    			int i = 0;
    			pStudents = (StudentDynamic*)malloc(sizeof(StudentDynamic) * 1);
    			while (!feof(pFile))
    			{
    				fscanf(pFile, "%s", auxfirstName);
    				pStudents[i].firstName = (char*)malloc(strlen(auxfirstName) + 1);
    				strcpy(pStudents[i].firstName, auxfirstName);
    
    				fscanf(pFile, "%s", auxlastName);
    				pStudents[i].lastName = (char*)malloc(strlen(auxlastName) + 1);
    				strcpy(pStudents[i].lastName, auxlastName);
    
    				fscanf(pFile, "%f", &auxGrade);
    				pStudents[i].grade = auxGrade;
    
    				i++;
    				pStudents = (StudentDynamic*)realloc(pStudents, sizeof(StudentDynamic) * (i + 1));
    			}
    			nStudents = i;
    			fclose(pFile);
    			break;
    
    		case '2':
    			pStudents = (StudentDynamic*)realloc(pStudents, sizeof(StudentDynamic) * (i + 1));
    			printf("Details of the new student:\n");
    			printf("First name: ");
    			scanf("%s", pStudents[i].firstName);
    
    			printf("Last Name: ");
    			scanf("%s", pStudents[i].lastName);
    
    			printf("Grade: ");
    			scanf("%d", &pStudents[i].grade);
    			break;
    
    		case '5':
    			char str[100];
    			printf("\n Enter the filename: ");
    			gets(str);
    			exportCSV(str, pStudents, nStudents);
    			break;
    
    		case '6':
    			printStudents(pStudents, nStudents);
    			break;
    
    		case '7':
    			for (int i = 0; i < nStudents; ++i)
    			{
    				free(pStudents[i].firstName);
    				free(pStudents[i].lastName);
    			}
    			free(pStudents);
    			printf("\n\n");
    			printf("\t\t     Thank you for using my application. Have a nice day. (-_-)");
    			printf("\n\n");
    			exit(0);
    
    		}
    
    	}
    
    	return 0;
    }
    And when I'm trying to add a new student I get my program crashed.
    Really? Your program won't even compile for me. Here are the problems detected by my compiler:

    Code:
    ||=== Build: Debug in c_homework (compiler: gcc 6.1.0) ===|
    main.c|13|warning: no previous declaration for ‘exportCSV’ [-Wmissing-declarations]|
    main.c|31|warning: no previous declaration for ‘printStudents’ [-Wmissing-declarations]|
    main.c||In function ‘main’:|
    main.c|67|warning: implicit declaration of function ‘getche’ [-Wimplicit-function-declaration]|
    main.c|72|error: a label can only be part of a statement and a declaration is not a statement|
    main.c|73|error: expected expression before ‘char’|
    main.c|79|warning: implicit declaration of function ‘exit’ [-Wimplicit-function-declaration]|
    main.c|79|warning: incompatible implicit declaration of built-in function ‘exit’|
    main.c|79|note: include ‘<stdlib.h>’ or provide a declaration of ‘exit’|
    main.c|81|warning: declaration of ‘i’ shadows a previous local [-Wshadow]|
    main.c|46|note: shadowed declaration is here|
    main.c|85|error: ‘auxfirstName’ undeclared (first use in this function)|
    main.c|85|note: each undeclared identifier is reported only once for each function it appears in|
    main.c|89|error: ‘auxlastName’ undeclared (first use in this function)|
    main.c|113|warning: format ‘%d’ expects argument of type ‘int *’, but argument 2 has type ‘float *’ [-Wformat=]|
    main.c|117|error: a label can only be part of a statement and a declaration is not a statement|
    main.c|119|warning: implicit declaration of function ‘gets’ [-Wimplicit-function-declaration]|
    main.c|128|warning: declaration of ‘i’ shadows a previous local [-Wshadow]|
    main.c|81|note: shadowed declaration is here|
    main.c|137|warning: incompatible implicit declaration of built-in function ‘exit’|
    main.c|137|note: include ‘<stdlib.h>’ or provide a declaration of ‘exit’|
    main.c|69|warning: switch missing default case [-Wswitch-default]|
    main.c|46|warning: unused variable ‘i’ [-Wunused-variable]|
    ||=== Build failed: 5 error(s), 12 warning(s) (0 minute(s), 0 second(s)) ===|

  5. #5
    Banned
    Join Date
    Aug 2017
    Posts
    861
    a strcu reflecting the same would be a good place to start, then declare one as an array, then put it in a loop then add your data to it, be it stdin or fstream the methodology is basically the same, the functions used will change. now to help your fix your code, can't fix the car unless you being it to the repair shop, post your code. belay last about posting code. this got posted just milliseconds later.

  6. #6
    Banned
    Join Date
    Aug 2017
    Posts
    861
    Quote Originally Posted by jimblumberg View Post
    Here is the code in question:
    yours or andreib14?
    anyways this is what I fixed but YES it needs to now be moved forward to get it to work properly,
    I commented out mistakes and made needed adjustments. gets does not work on mine either. might consider changing it to
    Code:
    fgets(str, sizeof str, stdin);


    Code:
    #include <malloc.h>
    #include <stdio.h>
    #include <malloc.h>
    #include <string.h>
    
    
    #include <stdlib.h> // exit
     
    typedef struct StudentDynamic
    {
        char* firstName;
        char* lastName;
        float grade;
    }StudentDynamic;
     
    void exportCSV(char *filename, StudentDynamic* pStudents, int nStudents)
    {
        printf("\n Creating %s.csv file. \n ", filename);
        FILE *fp;
        filename = strcat(filename, ".csv");
        fp = fopen(filename, "w+");
        fprintf(fp, "Student No., First Name, Last Name, Grade");
        for (int i = 0; i<nStudents; ++i)
        {
            fprintf(fp, "\n%d", i+1);
            fprintf(fp, ",%s ", pStudents[i].firstName);
            fprintf(fp, ",%s ", pStudents[i].lastName);
            fprintf(fp, ",%f ", pStudents[i].grade);
        }
        fclose(fp);
        printf("\n File %s succesfully created!\n", filename);
    }
     
    void printStudents(StudentDynamic* pStudents, int nStudents)
    {
        printf("========== List of Students ==========\n");
        for (int i = 0; i < nStudents; ++i)
        {
            printf("%d. %10s %10s %7.2f", i + 1,
                pStudents[i].firstName,
                pStudents[i].lastName,
                pStudents[i].grade);
            printf("\n");
        }
    }
     
    int main()
    { 
        //UNUSED VAR 
        int nStudents, i;
     
        char choice;
        printf("\t\t================== STUDENT DATABASE APPLICATION ==================");
        printf("\n\n                                          ");
        printf("\n\n");
        printf(" \n\t\t\t============================================");
        printf("\n \t\t\t  1. Read Students from Default File");
        printf("\n \t\t\t  2. Create Student");
        printf("\n \t\t\t  3. Update Record");
        printf("\n \t\t\t  4. Delete Record");
        printf("\n \t\t\t  5. Export DB to CSV");
        printf("\n \t\t\t  6. List Students");
        printf("\n \t\t\t  7. Exit Program");
        printf(" \n\t\t\t============================================");
        printf("\n\n");
        printf("\t\t\t Select Your Choice : ");
        
        // You cannot declare data types in a switch
        StudentDynamic* pStudents = NULL;
        char auxfirstName[100], auxlastName[100];
        float auxGrade;
         FILE* pFile = fopen("InitialDB.txt", "r");
         char str[100];
     
        while (1)
        {
         //   fflush(stdin);
    //        choice = getche();
            choice = getchar();
            printf("\n");
            switch (choice)
            {
            case '1':
             //   StudentDynamic* pStudents = NULL;
              //  char auxfirstName[100], auxlastName[100];
              //  float auxGrade;
               // FILE* pFile = fopen("InitialDB.txt", "r");
                if (pFile == NULL)
                {
                    printf("Could not open file or is empty! Exiting...");
                    exit(2);
                }
                int i = 0;
                pStudents = (StudentDynamic*)malloc(sizeof(StudentDynamic) * 1);
                while (!feof(pFile))
                {
                    fscanf(pFile, "%s", auxfirstName);
                    pStudents[i].firstName = (char*)malloc(strlen(auxfirstName) + 1);
                    strcpy(pStudents[i].firstName, auxfirstName);
     
                    fscanf(pFile, "%s", auxlastName);
                    pStudents[i].lastName = (char*)malloc(strlen(auxlastName) + 1);
                    strcpy(pStudents[i].lastName, auxlastName);
     
                    fscanf(pFile, "%f", &auxGrade);
                    pStudents[i].grade = auxGrade;
     
                    i++;
                    pStudents = (StudentDynamic*)realloc(pStudents, sizeof(StudentDynamic) * (i + 1));
                }
                nStudents = i;
                fclose(pFile);
                break;
     
            case '2':
                pStudents = (StudentDynamic*)realloc(pStudents, sizeof(StudentDynamic) * (i + 1));
                printf("Details of the new student:\n");
                printf("First name: ");
                scanf("%s", pStudents[i].firstName);
     
                printf("Last Name: ");
                scanf("%s", pStudents[i].lastName);
     
                printf("Grade: ");
           // you're telling it to get an int 
           // when you data type in struct is float
           //needs adjustment.
           //     scanf("%d", &pStudents[i].grade);
                break;
     
            case '5':
            //    char str[100];
                printf("\n Enter the filename: ");
           //term2.c:134:13: warning: implicit declaration of function 'gets' [-Wimplicit-function-declaration]
                // but is my compiler, Linux, I think you're using windows?
                gets(str);
                exportCSV(str, pStudents, nStudents);
                break;
     
            case '6':
                printStudents(pStudents, nStudents);
                break;
     
            case '7':
                for (int i = 0; i < nStudents; ++i)
                {
                    free(pStudents[i].firstName);
                    free(pStudents[i].lastName);
                }
                free(pStudents);
                printf("\n\n");
                printf("\t\t     Thank you for using my application. Have a nice day. (-_-)");
                printf("\n\n");
                exit(0);
     
            }
     
        }
     
        return 0;
    }
    Last edited by userxbw; 12-08-2017 at 10:02 AM.

  7. #7
    Registered User
    Join Date
    Dec 2017
    Posts
    6
    Sorry I forget to put the code with forum syntax.
    Thank you for helping me userxbw.
    I'm using Windows.
    But still got crash after i enter a new record on the choice 2. I think is an allocation problem but i can't resolve it

  8. #8
    Registered User
    Join Date
    May 2010
    Posts
    4,632
    But still got crash after i enter a new record on the choice 2.
    Did you fix all the issues pointed out in post #4? If so then you need to post your current code (in code tags).

    Your original program shouldn't even compile, so it should never crash.

    // You cannot declare data types in a switch
    Yes you can, you probably shouldn't, but you can by creating blocks.

  9. #9
    Registered User
    Join Date
    Dec 2017
    Posts
    6
    On my Visual Studio compilator it's all okey and i repaired what userxbw told me.

  10. #10
    Registered User
    Join Date
    May 2010
    Posts
    4,632
    Then you need to post your current code.

  11. #11
    Registered User
    Join Date
    Dec 2017
    Posts
    6
    Code:
    #include <malloc.h>
    #include <stdio.h>
    #include <malloc.h>
    #include <string.h>
    #include <stdlib.h>
    
    
    typedef struct StudentDynamic
    {
    	char* firstName;
    	char* lastName;
    	float grade;
    }StudentDynamic;
    
    
    void exportCSV(char *filename, StudentDynamic* pStudents, int nStudents)
    {
    	printf("\n Creating %s.csv file. \n ", filename);
    	FILE *fp;
    	filename = strcat(filename, ".csv");
    	fp = fopen(filename, "w+");
    	fprintf(fp, "Student No., First Name, Last Name, Grade");
    	for (int i = 0; i<nStudents; ++i)
    	{
    		fprintf(fp, "\n%d", i+1);
    		fprintf(fp, ",%s ", pStudents[i].firstName);
    		fprintf(fp, ",%s ", pStudents[i].lastName);
    		fprintf(fp, ",%f ", pStudents[i].grade);
    	}
    	fclose(fp);
    	printf("\n File %s succesfully created!\n", filename);
    }
    
    
    void printStudents(StudentDynamic* pStudents, int nStudents)
    {
    	printf("========== List of Students ==========\n");
    	for (int i = 0; i < nStudents; ++i)
    	{
    		printf("%d. %10s %10s %7.2f", i + 1,
    			pStudents[i].firstName,
    			pStudents[i].lastName,
    			pStudents[i].grade);
    		printf("\n");
    	}
    }
    
    
    int main()
    {
    	int nStudents, i;
    
    
    	char choice;
    	printf("\t\t================== STUDENT DATABASE APPLICATION ==================");
    	printf("\n\n");
    	printf(" \n\t\t\t============================================");
    	printf("\n \t\t\t  1. Read Students from Default File");
    	printf("\n \t\t\t  2. Create Student");
    	printf("\n \t\t\t  3. Update Record");
    	printf("\n \t\t\t  4. Delete Record");
    	printf("\n \t\t\t  5. Export DB to CSV");
    	printf("\n \t\t\t  6. List Students");
    	printf("\n \t\t\t  7. Exit Program");
    	printf(" \n\t\t\t============================================");
    	printf("\n\n");
    	printf("  Select Your Choice : ");
    	while (1)
    	{
    		choice = getchar();
    		printf("\n");
    		switch (choice)
    		{
    		case '1':
    			StudentDynamic* pStudents = NULL;
    			char auxfirstName[255], auxlastName[255];
    			float auxGrade;
    			FILE* pFile = fopen("InitialDB.txt", "r");
    			if (pFile == NULL)
    			{
    				printf("Could not open file or is empty! Exiting...");
    				exit(2);
    			}
    			int i = 0;
    			pStudents = (StudentDynamic*)malloc(sizeof(StudentDynamic) * 1);
    			while (!feof(pFile))
    			{
    				fscanf(pFile, "%s", auxfirstName);
    				pStudents[i].firstName = (char*)malloc(strlen(auxfirstName) + 1);
    				strcpy(pStudents[i].firstName, auxfirstName);
    
    
    				fscanf(pFile, "%s", auxlastName);
    				pStudents[i].lastName = (char*)malloc(strlen(auxlastName) + 1);
    				strcpy(pStudents[i].lastName, auxlastName);
    
    
    				fscanf(pFile, "%f", &auxGrade);
    				pStudents[i].grade = auxGrade;
    
    
    				i++;
    				pStudents = (StudentDynamic*)realloc(pStudents, sizeof(StudentDynamic) * (i + 1));
    			}
    			nStudents = i;
    			fclose(pFile);
    			printf("\n  Enter Another Choice : ");
    			break;
    
    
    		case '2':
    			pStudents = (StudentDynamic*)realloc(pStudents, sizeof(StudentDynamic) * (i + 1));
    			printf("Details of the new student:\n");
    			printf("First name: ");
    			scanf("%s", pStudents[i].firstName);
    
    
    			printf("Last Name: ");
    			scanf("%s", pStudents[i].lastName);
    
    
    			printf("Grade: ");
    			scanf("%f", &pStudents[i].grade);
    			printf("\n  Enter Another Choice : ");
    			break;
    
    
    		case '3':
    			break;
    
    
    		case '4':
    			int idtoDelete;
    			printf("Delete Records for student number: ");
    			scanf("%d", &idtoDelete);
    			--idtoDelete;
    			for (int i = idtoDelete; i < nStudents-1; ++i)
    			{
    				strcpy(pStudents[i].firstName, pStudents[i+1].firstName);
    				strcpy(pStudents[i].lastName, pStudents[i+1].lastName);
    				pStudents[i].grade = pStudents[i + 1].grade;
    			}
    			free(pStudents[nStudents - 1].firstName);
    			free(pStudents[nStudents - 1].lastName);
    			nStudents--;
    			printf("\n  Enter Another Choice : ");
    			break;
    
    
    		case '5':
    			char str[10];
    			printf("\n Enter the filename (max. 10 characters): ");
    			gets(str);
    			exportCSV(str, pStudents, nStudents);
    			printf("\n  Enter Another Choice : ");
    			break;
    
    
    		case '6':
    			printStudents(pStudents, nStudents);
    			printf("\n  Enter Another Choice : ");
    			break;
    
    
    		case '7':
    			for (int i = 0; i < nStudents; ++i)
    			{
    				free(pStudents[i].firstName);
    				free(pStudents[i].lastName);
    			}
    			free(pStudents);
    			printf("\n");
    			printf("\t\t     Thank you for using my application.");
    			printf("\n\n");
    			exit(0);
    		}
    	}
    	return 0;
    }

  12. #12
    Registered User
    Join Date
    May 2010
    Posts
    4,632
    Well it appears that you didn't make all the suggested changes. Here is what my compiler says about your code.
    Code:
    /main.c|16|warning: no previous declaration for ‘exportCSV’ [-Wmissing-declarations]|
    /main.c|35|warning: no previous declaration for ‘printStudents’ [-Wmissing-declarations]|
    /main.c||In function ‘main’:|
    /main.c|75|error: a label can only be part of a statement and a declaration is not a statement|
    /main.c|76|error: expected expression before ‘char’|
    /main.c|84|warning: declaration of ‘i’ shadows a previous local [-Wshadow]|
    /main.c|51|note: shadowed declaration is here|
    /main.c|88|error: ‘auxfirstName’ undeclared (first use in this function)|
    /main.c|88|note: each undeclared identifier is reported only once for each function it appears in|
    /main.c|93|error: ‘auxlastName’ undeclared (first use in this function)|
    /main.c|133|error: a label can only be part of a statement and a declaration is not a statement|
    /main.c|137|warning: declaration of ‘i’ shadows a previous local [-Wshadow]|
    /main.c|84|note: shadowed declaration is here|
    /main.c|151|error: a label can only be part of a statement and a declaration is not a statement|
    /main.c|153|warning: implicit declaration of function ‘gets’ [-Wimplicit-function-declaration]|
    /main.c|166|warning: declaration of ‘i’ shadows a previous local [-Wshadow]|
    /main.c|84|note: shadowed declaration is here|
    /main.c|72|warning: switch missing default case [-Wswitch-default]|
    /main.c|51|warning: unused variable ‘i’ [-Wunused-variable]|
    ||=== Build failed: 6 error(s), 8 warning(s) (0 minute(s), 0 second(s)) ===|

  13. #13
    Registered User
    Join Date
    Dec 2017
    Posts
    6
    What compiler do you use? :/

  14. #14
    Registered User
    Join Date
    May 2010
    Posts
    4,632
    I use gcc.

    The major problem is that you're trying to create variables inside a case statement. It is usually a mistake to try to create variables in a case statement, usually you would create the variables before the switch statement and just assign values to the variables inside the various case statements. But if you do need to create a variable that is only visible in that case statement you must create a block inside that case statement by using braces "{}".

  15. #15
    Banned
    Join Date
    Aug 2017
    Posts
    861
    the function call gets was deprecated in C++11 and removed from C++14.

    I use gcc
    you might want to switch to what I suggested
    Code:
            case '1':
             //   StudentDynamic* pStudents = NULL;
              //  char auxfirstName[100], auxlastName[100];
              //  float auxGrade;
               // FILE* pFile = fopen("InitialDB.txt", "r");
                if (pFile == NULL)
                {
                    printf("Could not open file or is empty! Exiting...");
                    exit(2);
                }
                
                // if you are reading from a default file, why are you trying
                //to create a new one here?
              //  pStudents = (StudentDynamic*)malloc(sizeof(StudentDynamic) * 1);
    by looking at your first 2 case statements , it looks to me that you maybe getting your logic mixed up a bit. case 1 reads from, so everything you have for that case that creates a file should not even be in there, you're reading from, case 2 is creating a new entry.

    I changed your message, made it into a function, then placed the function call for your message inside of your loop, where it belongs. if you ever get your code running on your side you should see why i said that. you might want to read your code and rethink it.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. need help with sorting students GPA
    By cprogisfun in forum C Programming
    Replies: 7
    Last Post: 12-10-2010, 06:14 AM
  2. request for students
    By djp in forum C Programming
    Replies: 5
    Last Post: 06-23-2003, 02:01 PM
  3. Any Computeach International Students/ex students??
    By stevey in forum A Brief History of Cprogramming.com
    Replies: 0
    Last Post: 03-26-2002, 04:12 PM

Tags for this Thread