Shay Fletcher
Shay Fletcher

Reputation: 35

Trying to understand the problems in my c code

I created a code with 4 functions:

  1. Data_duplication that checks if the name is already exists.

  2. Init that the function initializes through input from the user a set of names and a set of scores. Both arrays of the same size which called size. Whenever data is collected for arrays, they must be valid. If the user typed an invalid name, an error message should be printed and an alternate statistic requested. A valid score is complete between 0 and 100. A valid name meets the following conditions:

    • Begins with a large Latin letter.
    • All but the first characters are lowercase Latin characters.
    • Not already in the array. (The array must not contain the same name twice.)
  3. Find function that gets as parameters, an array of names, an array of grades, and the size of these arrays. In addition, it receives as a student name parameter. The function finds the student's position in the array of names, and returns its grade. If the student does not appear in the set, 1- will be returned.

  4. FreeAll that frees all the memory from the arrays.

PROBLEM:
When i enter for example that there are 3 students it is asking from me to write a fourth student and then it writes a grade that I don't know from where and gets out of the program.

Code:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
#define SIZE 20

int Data_duplication(char* temp, char** names, int line);
void Init(char*** names, int** grades, int* size);
int Find(char** names, int* grades, int size, char* name);
void FreeAll(char*** names, int** grades, int size);
int main()
{
    char** Names = NULL;
    int* Grades = NULL;
    int size, grade;
    char name[SIZE] = { 0 };
    Init(&Names, &Grades, &size);
    printf("Enter a student name\n");
    scanf("%s", name);
    grade = Find(Names, Grades, size, name);
    printf("%d", grade);
    FreeAll(&Names, &Grades, size);
    return 0;

}
void Init(char*** names, int** grades, int* size)
{
    int i, j, flag;
    int strlengh;
    char temp[SIZE] = { 0 };
    printf("Enter number of students\n");
    scanf("%d", size);
    *names = (char**)malloc((*size) * sizeof(char*));
    if (!(*names))
    {
        printf("Error");
        return;
    }
    *grades = (int*)malloc((*size) * sizeof(int));
    if (!*grades)
    {
        printf("Error");
        return;
    }
    for (i = 0; i < *size; i++)
    {
        printf("Enter a name\n");
        scanf("%s", temp);
        strlengh = strlen(temp);
        do
        {
            flag = 1;
            if (strlen(temp) > 20)//if it longer then it should be
                flag = 0;
            if (temp[0] > 'Z' || temp[0] < 'A') //start with capital letter
                flag = 0;
            for (j = 1; temp[j] != '\0'; j++)//all the letter is a lower case letters except from the first
            {
                if (temp[j] > 'z' || temp[j] < 'a')
                {
                    flag = 0;
                    break;
                }
            }
            if (Data_duplication(temp, *names, i))//if its not a name that already entered
            {
                flag = 0;
            }
            if (flag)//if the name is ok
            {
                (*names)[i] = (char*)malloc((strlengh + 1) * sizeof(char));
                if (!(*names)[i])
                {
                    printf("Error");
                    return;
                }
                strcpy((*names)[i], temp);
            }
            else//if somthing wrong
            {
                printf("Bad name,try again.\n");
                scanf("%s", temp);
            }
        } while (!flag);

        printf("Enter grade\n");
        scanf("%d", (*grades + i));
        while (*(*grades + i) < 0 || *(*grades + i) > 100)//if the grade between 0 to 100
        {
            printf("Bad grade,try again.\n");
            scanf("%d", (*grades + i));
        }
    }

}
int Data_duplication(char* temp, char** names, int line)//find if there is another name like this that already entered
{
    for (int i = 0; i < line; i++)
    {
        if (!strcmp(temp, names[i]))
        {
            return 1;
        }
    }
    return 0;
}
int Find(char** names, int* grades, int size, char* name)
{
    int i;
    for (i = 0; i < size; i++)
    {
        if (strcmp(name, names[i]) == 0);
        {
            return (*(grades + i));
        }
    }
    return -1;
}
void FreeAll(char*** names, int** grades, int size)//free al the dynamic memo allocation
{
    for (int i = 0; i < size; i++)
    {
        free(*(*names + i));
    }
    free(*names);
    free(*grades);

}

Upvotes: 0

Views: 52

Answers (1)

user13453676
user13453676

Reputation:

arrays passed by reference so you don't need to pass pointer to array. I made changes in your code.

#include <stdio.h>
#include <stdlib.h>
#include<malloc.h> 
#include<string.h>
#define SIZE   20
int Data_duplication(char* temp, char** names, int line);
void Init(char** names, int* grades, int size);
int Find(char** names, int* grades, int size, char* name);
void FreeAll(char** names, int* grades, int size);
int main()
{

    int size, grade;
    char name[SIZE];
    printf("Enter number of students\n");
    scanf("%d", &size);
    char** Names=(char**)malloc((size) * sizeof(char*));
    int* Grades= (int*)malloc((size) * sizeof(int));
    Init(Names, Grades, size);
    printf("--------------------------------------------------------------------\n");
    printf("Enter a student name\n");
    scanf("%s",name);
    grade = Find(Names,Grades,size,name);
    printf("%d", grade);
    FreeAll(Names, Grades, size);
    return 0;

}
void Init(char** names, int* grades, int size)
{
    int i, j, flag;
    int strlengh;
    if (!(names))
    {
        printf("Error");
        return;
    }
    for(i = 0; i < size ; i++){
        names[i] = malloc(sizeof(char)*SIZE);
        if(!names[i])
        {
            printf("Error");
            return;
        }
    }
    if (!grades)
    {
        printf("Error");
        return;
    }
    for (i = 0; i < size; i++)
    {
     printf("Student i= %d\n",i); 
        do
        {
            char temp[SIZE]="";

            printf("Enter a name\n");
            scanf("%s", temp);

            strlengh = strlen(temp);
            flag = 1;
            if (strlen(temp) > SIZE)//if it longer then it should be
                flag = 0;
            if (temp[0] > 'Z' || temp[0] < 'A') //start with capital letter
                flag = 0;
            for (j = 1; temp[j] != '\0'; j++)//all the letter is a lower case letters except from the first
            {
                if (temp[j] > 'z' || temp[j] < 'a')
                {
                    flag = 0;
                    break;
                }
            }
            if (Data_duplication(temp, names, i))//if its not a name that already entered
            {
                flag = 0;
            }
            if (flag)//if the name is ok
            {
              strcpy(names[i], temp);
              printf("temp= %s\n", temp);
              printf("names[i]= %s\n", names[i]);


            }
            else//if somthing wrong
            {
                printf("Bad name,try again.\n");
            }
        } while (!flag);

        printf("Enter grade\n");
        scanf("%d",&grades[i]);
        while (grades[i] < 0 || grades[i] > 100)//if the grade between 0 to 100
        {
            printf("Bad grade,try again.\n");
            scanf("%d",&grades[i]);

        }
    }

}
int Data_duplication(char* temp, char** names, int line)//find if there is another name like this that already entered
{
    for (int i = 0; i < line; i++)
    {
        if (!strcmp(temp, names[i]))
        {
            return 1;
        }
    }
    return 0;
}
int Find(char** names, int* grades, int size, char* name)
{
    int i;
    for (i = 0; i < size; i++)
    {
        printf("name= %s\n",name);
        printf("names[i]= %s\n", names[i]);
        if (strcmp(name, names[i]) == 0)
        {
            return (grades[i]);
        }
    }
    return -1;
}
void FreeAll(char** names, int* grades, int size)//free al the dynamic memo allocation
{
    for (int i = 0; i < size; i++)
    {
        free(names[i]);
    }
    free(names);
    free(grades);

}

Upvotes: 0

Related Questions