Use of strings in structs in C language - c

I've been studying C for almost three months now and I neved had much trouble on the way. However, I have this task to create a program that will arrange an array of products (chosen by the user), either by their price or their available quantity.
I had to use a struct called Product to do so. Problem is, when I enter on any of the functions (arrangePrice or arrangeQuantity), the console prints the "What is the name of product?" printf command and IMMEDIATELY prints out the "What is the price of the product?" printf command. It simply seems to ignore the scanf function between those commands that would let the user write the name of the product on a string. Why is that happening???
Here is the entire code:
#include <stdio.h>
#include <string.h>
struct Product
{
char name[80];
double price;
int quantity;
};
void arrangePrice(struct Product vet[], int n)
{
int i, j, auxQuant;
double aux, auxprice;
char auxname[80];
for (i = 0; i < n; i++)
{
printf("What is the name of the product?\n");
scanf("%[^\n]", vet[i].name);
printf("What is the price of the product?\n");
scanf("%lf", &vet[i].price);
printf("What is the available quantity of the product?\n");
scanf("%d", &vet[i].quantity);
}
printf("\n\nArranging by price:\n\n");
for (j = 0; j < n; j++)
{
aux = vet[j].price;
for (i = j + 1; i < n; i++)
{
if (vet[i].price < aux)
{
auxprice = vet[i].price;
strcpy(auxname, vet[i].name);
auxQuant = vet[i].quantity;
vet[i] = vet[j];
strcpy(vet[j].name, auxname);
vet[j].price = auxprice;
vet[j].quantity = auxQuant;
}
}
}
for (i = 0; i < n; i++)
{
printf("%[^\n] -> %.2lf\n", vet[i].name, vet[i].price);
}
}
void arrangeQuant(struct Product vet[], int n)
{
int i, j, aux, auxQuant;
double auxprice;
char auxname[80];
for (i = 0; i < n; i++)
{
printf("What is the name of the product?\n");
scanf("%[^\n]", vet[i].name);
printf("What is the price of the product?\n");
scanf("%lf", &vet[i].price);
printf("What is the available quantity of the product?\n");
scanf("%d", &vet[i].quantity);
}
printf("\n\nArranging by available quantity:\n\n");
for (j = 0; j < n; j++)
{
aux = vet[j].quantity;
for (i = j + 1; i < n; i++)
{
if (vet[i].quantity < aux)
{
auxprice = vet[i].price;
strcpy(auxname, vet[i].name);
auxQuant = vet[i].quantity;
vet[i] = vet[j];
strcpy(vet[j].name, auxname);
vet[j].price = auxprice;
vet[j].quantity = auxQuant;
}
}
}
for (i = 0; i < n; i++)
{
printf("%[^\n] -> %d\n", vet[i].name, vet[i].quantity);
}
}
int main()
{
struct Product prod[51];
int n;
int choice;
printf("How many products will be added? (Maximum of 50)\n");
scanf("%d", &n);
while (n < 1 || n > 50)
{
printf("Invalid value. Try again.\n");
scanf("%d", &n);
}
printf("Do you want to arrange by price or by available quantity? (0 or 1)\n");
scanf("%d", &choice);
if (choice == 0) arrangePrice(prod, n);
else if (choice == 1) arrangeQuant(prod, n);
else printf("Invalid value.\n");
return 0;
}
I must say that I actually still don't know if the code is right or not, since I couldn't type the name of the products. Thanks for any help!

Your scanf calls are leaving newline characters in the input buffer, and those newlines are being read on subsequent calls.
You need to leave a space at the start of each scanf pattern to consume any newlines that may be left over.
Also, %[^\n] is not a valid format specifier for printf. Use %s instead.
Example:
printf("What is the name of the product?\n");
scanf(" %s", vet[i].name); // use %s for strings
printf("What is the price of the product?\n");
scanf(" %lf", &vet[i].price);
printf("What is the available quantity of the product?\n");
scanf(" %d", &vet[i].quantity);
And:
printf("How many products will be added? (Maximum of 50)\n");
scanf(" %d", &n);
while (n < 1 || n > 50)
{
printf("Invalid value. Try again.\n");
scanf(" %d", &n);
}
printf("Do you want to arrange by price or by available quantity? (0 or 1)\n");
scanf(" %d", &choice);

struct product vet[] is a pointer. It doesn't actually point to an array unless you allocate such an array before you call arrangePrice. For example:
struct Product vet_array[ 2 ];
arrangePrice( vet_array, 2 );
Alternatively you could call malloc but just to get this started to work, allocate a local on the stack with a fixed number of elements.

Related

Controlling user input in regards to strings in bidimensional arrays

I'm trying to allow the user to only write names of students in uppercase in C.
I've tried :
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main() {
int number_ofstudents, i, j;
char Name[100][20];
do {
printf("Enter number of students \n");
scanf("%i", &number_ofstudents);
} while ((number_ofstudents < 0) || (number_ofstudents > 100));
for (i = 0; i < number_ofstudents; i++) {
for (j = 0; j <= strlen(Name[i]) - 1; j++) {
printf("Enter the name of student number %i in uppercase \n", i + 1);
do {
fflush(stdin);
fgets(Name[i], 20, stdin);
} while ((Name[i][j] < 'A') || (Name[i][j] > 'Z'));
}
}
return 0;
}
I've also tried:
for (i = 0; i < number_ofstudents; i++) {
for (j = 0; j <= Name[i][j] != '\0'; j++) {
printf("Enter the name of student number %i in uppercase \n", i + 1);
do {
fflush(stdin);
fgets(Name[i], 20, stdin);
} while ((Name[i][j] < 'A') || (Name[i][j] > 'Z'));
}
}
What I'm expecting is for the program to keep demanding that I enter the name of the student number x until my input is all in uppercase, however once I execute none of my inputs are accepted and the phrase "Enter the name of student number 1 in uppercase " keeps repeating itself.
Does the issue lie in my 2nd for loop when I'm trying to manipulate the letter input? I haven't learned pointers or functions yet.

Create a Menu for users to choose whether they want to add/remove/search for numbers using an array

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.

Wrong Results Being Printed in C After Being Inserted in 2D Char Array

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

C Print Data from loop after loop ends

So, I managed to wrangle some code to get part of my program working. My program has to have a prompt to enter grades (done), repeat in a loop until broken (doneish), and print results of each grade entered. The last part is where I am stuck. I can't seem to find a good way to get any grade I entered to print at the end. I just want a "you entered ###, ###, ###," or something similar, but it can be up to 100 numbers. Below is what I have so far
#include <stdio.h>
#define MAX_ARRAY_SIZE 100
int main(void) {
int grade[MAX_ARRAY_SIZE];
int entryCount = 0;
char continueResponse;
printf("Enter an grade of between 1 and 100. \n");
printf("Enter a maximum of %d grades. \n", MAX_ARRAY_SIZE);
int i;
for(i = 0; i < MAX_ARRAY_SIZE; i++) {
printf("Enter grade: ");
scanf("%d", &grade[i]);
printf("Continue? (y/n): ");
scanf(" %c", &continueResponse);
entryCount++;
if(continueResponse == 'n' || continueResponse == 'N') {
printf(" == End of Data Entry ==\n\n");
break;
}
}
return 0;
}
Keep in mind this is third week of doing this, so I know next to nothing. If there's a "why did you do this like this", the answer is because that's how I've done it before and it works. I appreciate any input!
After your dataentry loop:
for(i = 0; i < MAX_ARRAY_SIZE; i++) {
...
}
You just have to add a second loop:
for(i = 0; i < entryCount; i++) {
printf ("%d ", grade[i]);
}
You've recorded entryCount entries to the array, numbered 0 ... entryCount - 1; you'd use another for loop to print them. For nicer formatting we do not print ", " after the last number:
printf("You've entered ");
for (i = 0; i < entryCount; i++) {
if (i == entryCount - 1) {
printf("%d", grade[i]);
}
else {
printf("%d, ", grade[i]);
}
}
printf("\n");
what I understood about your problem the following code would work:
#include <stdio.h>
#define MAX_ARRAY_SIZE 100
int main(void) {
int grade[MAX_ARRAY_SIZE];
int entryCount = 0;
char continueResponse;
printf("Enter an grade of between 1 and 100. \n");
printf("Enter a maximum of %d grades. \n", MAX_ARRAY_SIZE);
int i;
for(i = 0; i < MAX_ARRAY_SIZE; i++) {
printf("Enter grade: ");
scanf("%d", &grade[i]);
printf("Continue? (y/n): ");
scanf(" %c", &continueResponse);
entryCount++;
printf("you entred:\n");
for(int j=0;j<entryCount;j++)
{
printf("%d ",grade[j]);
}
if(continueResponse == 'n' || continueResponse == 'N') {
printf(" == End of Data Entry ==\n\n");
break;
}
}
return 0;
}

program crashing using 2D dynamic string array in c

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.)

Resources