function gets an array of grades and changes the amount of grades if there are less elements than before the function will delete those elements
for example: before: I entered in another function 3 grades: 100, 90, 80.
after: In this function it asked me to enter new amount, and I entered, and then entered it's grade, 70.
after I return it to the main and sending the array, grades, to a function which prints the array and it's stays with 3 elements, 100, 90, 80.
please help me i tried a lot of time and didn't succeed.
void changeNumOfGrades(int* grades, int size)
{
int numOfGrades = 0;
int i = 0;
do
{
if (i > ONE_ITERATION)
{
printf("Please enter positive number...\n");
}
printf("How many elements would you like? ");
scanf("%d", &numOfGrades);
i += 1;
} while (numOfGrades < 0);
grades = realloc(grades, numOfGrades*sizeof(int));
if (!grades)
{
printf("Unsuccessful realloc");
//There is no need to release memory because the realloc is for the same pointer.
}
if (numOfGrades > size)
{
printf("You have more grades than before,\nPlease enter their grades: \n");
int newGrade = 0;
//int newNumOfGrades = numOfGrades - size;
int i = 0;
for (i = size + 1; i <= numOfGrades; i++)
{
printf("Enter grade number %d: ", i);
scanf("%d", &newGrade);
*(grades + i - 1) = newGrade;
printf("hey %d", *(grades + 1));
}
}
}
In order for you to reallocate grades, you need to pass as **grades.
For test reasons, I have changed size to get the new allocation size, so you can print the array after the changeNumOfGrades
void changeNumOfGrades(int** grades, int *size/*get new size*/)
{
int numOfGrades = 0;
int i = 0;
do
{
if (i > ONE_ITERATION)
{
printf("Please enter positive number...\n");
}
printf("How many elements would you like? ");
scanf("%d", &numOfGrades);
i ++;
} while (numOfGrades < 0);
printf("%d",numOfGrades);
*grades = realloc(*grades, numOfGrades*sizeof(int));/*realloc **grade */
if (!grades)
{
printf("Unsuccessful realloc");
//There is no need to release memory because the realloc is for the same pointer.
}
printf("...\n");
if (numOfGrades > *size)
{
printf("You have more grades than before,\nPlease enter their grades: \n");
int newGrade = 0;
//int newNumOfGrades = numOfGrades - size;
int i = 0;
for (i = *size + 1; i <= numOfGrades; i++)
{
printf("Enter grade number %d: ", i);
scanf("%d", &newGrade);
*(*grades + i - 1) = newGrade;
//printf("hey %d", *(grades + 1));
}
}
*size = numOfGrades;/*get new size allocated*/
}
void main()
{
int numOfInts;
int *grades ;
grades = malloc(3*sizeof(int));
memset(grades,0,sizeof(int)*3);
grades[0]=100;
grades[1]=80;
grades[2]=20;
numOfInts = 3;/*initialize 3 items*/
changeNumOfGrades(&grades,&numOfInts);
printf("\n\n");
for (int i=0;i<numOfInts;i++)
{
printf("%d\n",grades[i]);
}
free(grades);
}
Related
I want to build a simple user Menu for the user to add/remove and to search for numbers through an array. However, the problem that I am facing is that after successfully running the code and adding numbers to a global array. When choosing the remove option, It showed the list of the array but array1 is not the value of the array I entered, but a total length of the array instead.enter image description here. Please show me which parts that I coded or wrote wrong and excuse me for my bad english! Thank you so much in advance.
#include <stdio.h>
#include <string.h>
int arr[] = {};
int arrLength = 0;
void add(int lengthCheck){
int i,n,check = 0;
do{
printf("\nPlease add a number: ");
scanf("%d",&n);
fflush(stdin);
arr[lengthCheck] = n;
lengthCheck++;
printf("\nNew Array:");
for (i = 0; i < lengthCheck; i++){
printf("\t%d ", arr[i]);
}
printf("\n\n Do you want to continue adding? (y = 0 | n = 1)\n");
scanf("%d", &check);
fflush(stdin);
} while (check < 1);
arrLength = lengthCheck;
}
void remove(int lengthCheck){
int m, i, loop, count = 0;
printf("\nArray:");
for(loop = 0; loop < lengthCheck; loop++){
printf(" %d", arr[loop]);
}
printf("\n\nPlease chooose a number to remove: ");
scanf("%d",&m);
fflush(stdin);
for(loop = 0; loop < lengthCheck; loop++) {
if(arr[loop] == m) {
break;
}
count++;
}
for(i=count; i<lengthCheck - 1; i++)
{
arr[i] = arr[i + 1];
}
lengthCheck--;
printf("\nNew array are : ");
for(i=0; i<lengthCheck; i++)
{
printf("%d\t", arr[i]);
}
}
void search(int arrLength){
int check, loop, t, u;
printf("\nPlease enter a number to check if it exists in the array: ");
scanf("%d",&check);
fflush(stdin);
for(loop = 0; loop < arrLength; loop++) {
if(arr[loop] == check) {
printf("\n\tPosition number %d in the array contains %d\n\n", t,check);
u++;
}
t++;
}
printf("The number %d exist in %d position(s) of the array",check,u);
}
int main(){
int ch, z;
for (z = 0; z < 1;) {
printf("Enter Choice: \n\t(0) for add \n\t(1) for remove \n\t(2) for search\n\t(3) for exit\n");
scanf("%d", &ch);
fflush(stdin);
switch(ch) {
case 0:
add(arrLength);
break;
case 1:
remove(arrLength);
break;
case 2:
search(arrLength);
break;
case 3:
z = 1;
break;
}
}
return 0;
}
you cannot declare an empty array and just add values to it in C.
int arr[] = {};
You need to allocate space for your array upfront, or using malloc to allocate the memory for it later.
This will allocate memory space to store three ints in they array and initialize each element to zero:
int arr[3] = {0};
You will have to check that it never goes above the number of elements declared in the array. If you try to use more space than pre-allocated in the array, you are causing a buffer overflow and all it does is corrupt memory.
I created a code with 4 functions:
Data_duplication that checks if the name is already exists.
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.)
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.
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);
}
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);
}
int const size = 100;
float grades[size];
char students[size][size];
char temp_students[size][size];
int main() {
int length = 0;
int i = 0;
float g = 0;
printf("How many students do you want to enter? \n ");
scanf("%d", &length);
while((i < length)){
printf("Enter the name and grade \n");
// scanf("%s", students[i]);
char temp;
scanf("%c",&temp); // temp statement to clear buffer
scanf("%[^\n]", students[i]);
strcpy(temp_students[i], students[i]);
printf("Enter the grade again \n");
scanf(" %f", &g);
grades[i] = g;
insertion_sort_float(grades, g, length);
insertion_sort_string(students, students[i], length);
i++;
}
i--;
print_report(grades, students, length);
}
void print_report(float grades[], char students[size][size], int number){
printf("Students Test Report \n");
printf("Students that took the test: %d \n", number);
for (int i = 0; i < number; i++){
for(int j = 0; j < number; j++){
printf("%c", students[i][j]);
}
printf("\n");
}
double average = average_number(grades, number);
double median = median_number(grades, number);
double highest = max_number(grades, number);
double lowest = min_number(grades, number);
printf("Average: %f \n Median: %f \n Highest: %f \n Lowest: %f \n", average, median, highest, lowest);
}
void insertion_sort_string(char students[size][size], char string[], int array_size) {
if (array_size+ 1 < size) {// only do insert when there is free space in array
if (array_size == 0)//empty array, insert at the top directly
strcpy(students[0], string);
int insert_index;//to identify the location
for (int i = 0; i < array_size + 1; i++) {
insert_index = i;
if (strcmp(students[i], string)) // due the sorted property of array,
break;// where the first bigger item showes up, where we should insert
}//end of the first for loop
// if we don't find any bigger item, inset_index will equal to element_num, which means we insert at the tail
for (int j = array_size; j > insert_index; j--) {
strcpy(students[j], students[j-1]);
}// end of the second loop
strcpy(students[insert_index], string); // do the insert
} else {
printf("overflow!");
return;
}
}
This is what happens when the code is run:
Write a program that allows a user to enter the names of students that took a test along with the grades they received.
I am not sure why none of the other names are being stored. Only Gerar is being printed. Also the entire string should be printed: "Gerard 78.5", but that is not happening either.
Some code omitted for post purposes. But important code is included
I am having a problem with this code:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main(void)
{
int num=0;
printf("Enter number of entries: ");
scanf_s("%d", &num);
char **firstname=NULL;
char **lastname=NULL;
float *score=NULL;
int i;
firstname = malloc(num * (sizeof(char*)));
for (i = 0; i < num; i++)
{
firstname[i] = malloc(21);
}
lastname = malloc(num * (sizeof(char*)));
for (i = 0; i < num; i++)
{
lastname[i] = malloc(21);
}
score = ((float*)malloc(num* (sizeof(float))));
for (i = 1; i <= num; i++)
{
printf("Enter the first name of entry %d: \n", i);
scanf_s("%s", firstname[i], 21);
printf("Enter the last name of entry %d: \n", i);
scanf_s("%s", lastname[i], 21);
printf("Enter the score of entry %d: \n", i);
scanf_s("%f", score[i]);
}
for (i = 0; i < num; ++i)
{
printf("%s, %s, %f", firstname[i], lastname[i], score[i]);
}
return 0;
}
I have edited the code with the suggested changes, and now it prints random characters and a random value for the first and last name, as well as the score. the code also crashes if there is more than one iteration of input (after asking for the score of the first entry, it crashes before asking for the first name of the second entry.)
Ok, so I am writing a program that reads input from a file and puts them into arrays. I am trying to use pointers with arrays so I can point to a certain spot in an array and add a user defined float to the float that already exists.
This is my code so far:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int menu1();
int main()
{
FILE * ifp = fopen("input2.txt","r"); //Open the input file
int cars = 5, i , j, k; // Initialized cars and counters i, j, and k
char *VIEW="VIEW", *BID="BID", *CLOSE="CLOSE", choice1[20]; //Initialize character arrays
float START_BID[5]={0.00}, MIN_BID[5]={0.00}, CUR_BID[5]={0.00}, USR_BID[5]=0.00};
int compareLimit = 100, selection=0;
//Scan the file and appropriate the numbers into their respective arrays
for (i = 0; i < cars; i++)
{
fscanf(ifp, "%f %f", &START_BID[i],&MIN_BID[i]);
}
printf("Welcome to the Silent Auction\n\n");
menu1(); //Display the menu
scanf("%s", &choice1); //
int result = strncmp(choice1, VIEW, compareLimit); //Compare two strings
if(result == 0)
{
selection = selection + 1;
}
int result2 = strncmp(choice1, BID, compareLimit); //Compare two strings
if(result2 == 0)
{
selection = selection + 2;
}
int result3 = strncmp(choice1, CLOSE, compareLimit); //Compare two strings
if(result3 == 0)
{
selection = selection + 3;
}
while (selection < 3)
{
if (selection == 1)
{
printf("Number\tCurrent Bid\tMinimum Increase\n");
printf("1\t$%.2f\t\t$%.2f\n",CUR_BID[0], MIN_BID[0]);
printf("2\t$%.2f\t\t$%.2f\n",CUR_BID[1], MIN_BID[1]);
printf("3\t$%.2f\t\t$%.2f\n",CUR_BID[2], MIN_BID[2]);
printf("4\t$%.2f\t\t$%.2f\n",CUR_BID[3], MIN_BID[3]);
printf("5\t$%.2f\t\t$%.2f\n",CUR_BID[4], MIN_BID[4]);
menu1();
scanf("%s", &choice1);
}
else if (selection == 2)
{
int k;
float usr_bid;
printf("Which auction would you like to bid on? (1-5)\n");
scanf("%d", k);
if (CUR_BID[k - 1] = 0.00)
MIN_BID[k - 1] = START_BID[k - 1];
else
MIN_BID[k - 1] = CUR_BID[k - 1] + MIN_BID[k - 1];
printf("The minimum bid is %.2f\n", MIN_BID[k - 1]);
printf("How much would you like to bid?\n");
scanf("%f", usr_bid);
if (usr_bid < MIN_BID[k-1])
printf("Sorry, that bid is not high enough.\n");
else
CUR_BID[k - 1] = usr_bid + CUR_BID[k - 1];
menu1();
scanf("%s", &choice1);
}
else
{
int i;
int auction = 1;
for (i=0; i < cars; i++)
{
for (auction = 1; auction < cars; auction++)
{
while (CUR_BID[i]!= 0.00)
printf("Auction %d sold for $%.2f", auction, CUR_BID);
}
}
}
}
fclose(ifp);
return 0;
}
int menu1()
{
printf("Please make a selection (In all caps):\n");
printf("\tView Auctions [VIEW]\n");
printf("\tBid on an Auction [BID]\n");
printf("\tClose Auctions [CLOSE]\n");
}
My program works up to the while loop where else if (selection == 2) is. It asks me which
auction I want. And when I give it a number, it just freezes, crashes, and doesn't give me any errors other than Process terminated with status -1073741510.
Any ideas?
The pointers you pass to scanf() are incorrect.
Change:
scanf("%d", k);
to
scanf("%d", &k);
and change:
scanf("%s", &choice1); //
to
scanf("%s", choice1); //
in two places.