Array for storing names and grades of students in C - c

I am trying to make a small program in C which will store the first name, last name, and grade of an user inputted number of students. My biggest issue so far is on how to get for the names and grades of each student to print in a new line. With the string operator, I get an error, and with the char operator I only get the first letter and the grade. How would I go about getting the names to fully print? Thanks for all the help in advance.
#include <stdio.h>
#include <stdlib.h>
int main(){
int classsize,i;
printf("Please indicate number of records you want to enter (min 5, max 15):\n");
scanf("%d", &classsize);
char *first, *last;
double *mark;
first=(char*)malloc(classsize*sizeof(char));
last=(char*)malloc(classsize*sizeof(char));
mark=(double*)malloc(classsize*sizeof(double));
printf("Please input records of students (enter a new line after each record), with following format 1. first name 2. last name 3. score.\n");
for (i=0; i<classsize; i++) {
scanf("%s", &first[i]);
scanf("%s", &last[i]);
scanf("%lf", &mark[i]);
}
for (i=0; i<classsize; i++) {
printf("%s, %s has a %lf\n", *(first+i), *(last+i), *(mark+i));
}
}

With
char *first, *last;
You can store only 1 string in the variables as string in C is char *. first is char * and first[i] is char so you have errors related to that. You want first to be char ** and first[i] as char *.
You want
char **first, **last;
And change allocation to (note you don't need to typecast malloc)
//---------------------------------v
first=malloc(classsize*sizeof(char *));
And then in for loop allocate memory for each char * in first and last before reading names in that.
first[i] = malloc(some_size * sizeof(char));
...

Related

User Input to Array of Structs C

I am creating a program that gets user input and puts it into a struct called Student before returning back to a main menu. From the main menu you can add another student. This works but when I try to print all of the Students data that has been added to the array of structs it only prints the last Student that was added.
Here is the struct:
struct Student
{
char* firstName;
int age, cuid;
float GPA;
};
This is how I'm allocating space for the array in main:
struct Student* studentArray = malloc(*recordMaxPtr * sizeof(struct Student));
Here are the functions that capture user input and print the array:
// Gets info and adds student to the array of structs
void addStudents(struct Student* s, int *numStudents)
{
// Allocate memory for the first name
char *firstName = (char*) malloc(25*sizeof(char));
// Gets the name of student
printf("What is the name of the student you'd like to add? ");
gets(s->firstName);
printf("\n"); // blank line
// Gets age of student
printf("How old is the student? ");
scanf("%d", &s->age);
printf("\n"); // blank line
// Gets CUID
printf("What is his / her CUID number? ");
scanf("%d", &s->cuid);
printf("\n"); // blank line
// Gets GPA
printf("What is the student's GPA? ");
scanf("%f", &s->GPA);
printf("\n"); // blank line
}
// Sorts the array and then lists all of the saved students
void printStudents(struct Student* s, int *numStudents)
{
//bsort();
for (int i = 0; i < *numStudents; i++)
{
printf("Student #%d\n", i + 1);
printf(" Student's Name: %s\n", s[i].firstName);
printf(" Age: %d\n", s[i].age);
printf(" CUID: %d\n", s[i].cuid);
printf(" GPA: %2f\n", s[i].GPA);
}
}
I thought about trying to use a for loop to gather all of the student's data that I need at once but this is a school project and I'm not allowed to do it that way. I've been trying to figure this out for a while and I've sort of hit a brick wall on what to do. My best guess is that data is getting overwritten every time you enter a new student to the array but I'm not sure how to fix that.
You allocated a memory for the first name, but didn't save that anywhere. You have to store the address to the structure.
// Allocate memory for the first name
char *firstName = (char*) malloc(25*sizeof(char));
s->firstName = firstName; // add this
Also here are some more things to do for better code:
Check if malloc() succeeded
Check if scanf() succeeded
Replace gets() with fgets() and removal of newline character (gets() has unavoidable risk of buffer overrun and removed from new C specification)
Remove the cast of result of malloc() (c - Do I cast the result of malloc? - Stack Overflow)

How to show the result of written strings

I'm learning C Programming and I can't resolve this issue.
This is my code:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int first;
printf("Write Down Your First Name!\n\n");
scanf("%s", &first);
int last;
printf("\nNow Write Your Sir Name!\n\n");
scanf("%s", &last);
printf("\nYour Full Name is %s\n\n");
system("pause");
return 0;
}
And I want to show the full name written.
Should I use void?
Thanks in advance
first and last should be of char array type instead of int type if you want to store characters into that.
int first; ---> char first[100]; /* define how many char you want in first*/
similarly
int last; --> char last[100];
And while scanning it you don't have to pass &
scanf("%s", first);
scanf("%s", last);
Want to print/show ?
printf("\nNow Write Your Sir Name! %s n\n", first);/* you missed to pass argument to printf */
printf("\nYour Full Name is %s\n\n",first);
How to join both ? Iterate last upto '\0' char and copy each char of last to end of first
int len = strlen(first);
first[len] = ' ';/* if needed, put space at the end of first */
for( i = 0, j = len + 1 ; last[i]!='\0;i++,j++) {
first[j] = last[i]; /* first should have enough space */
}
first[j] = '\0';
Now print it as
printf("\nYour Full Name is %s\n\n",first);

Find Biggest Number in C, by N number of inputs

So I have this code:
#include <stdio.h>
int main()
{
char peopleName[5][20],peopleAge[5];
int i;
int maxAge=0, maxName=-1;
for(i=0;i<5;i++)
{
printf("Name & Age %d :",i+1);
scanf("%s",&peopleName[i]);
scanf("%d",&peopleAge[i]);
if(peopleAge[i]>maxAge)
{
maxAge=peopleAge[i];
maxName=i;
}
}
printf("%s %d", peopleName[maxName],peopleAge[maxAge]);
}
This code finds from 5 people the oldest one. I want to change from 5 people to N number of people, whatever the number I input myself. (For example I put 7, and I can insert seven names and ages and so on).
The question has two parts: How does the user specify how many persons are entered? And how do I store the data?
The second part is easy: No matter how many persons you are going to consider, if you just want to know who is the oldest, it is enough to keep the name and age of the currently oldest person. (Of course, if there is a tie and many people are, say, 80 years old, you just get to keep the first match.)
Not storing anything also simplifies the first question. You could ask the user to specify the number of persons beforehand and that's find if you have few people. If you have a list of many people, the user would have to count the by hand and then enter the count. Miscounting is very likely.
A better way is to indicate the end of input by another means, for example by a negative age or by two dashes as name. There is also the possibility that the input runs out, for example when redirecting input from a file or when pressing one of Ctrl-Z or Ctrl-D, depending on your platform, after the input.
The example below read the input line-wise and then scans that line. The loop while (1) is in theory infinite, in practice execution breaks out of the loop when the input runs out – fgets return NULL –, when a blank line is read or when the input isn't in the format single-word name and age.
#include <stdio.h>
int main(void)
{
char oldest[80] = "no-one";
int max_age = -1;
int count = 0;
puts("Enter name & age on each line, blank line to stop:");
while (1) {
char line[80];
char name[80];
int age;
if (fgets(line, sizeof(line), stdin) == NULL) break;
if (sscanf(line, "%s %d", name, &age) < 2) break;
if (age > max_age) {
strcpy(oldest, name);
max_age = age;
}
count++;
}
printf("The oldest of these %d people is %s, aged %d.\n",
count, oldest, max_age);
return 0;
}
You can do this -
int n; // number of people
scanf("%d",&n); // take input from user
char peopleName[n][20],peopleAge[n]; // declare 2-d array
for(i=0;i<n;i++)
{
// your code
}
Also this statement -
scanf("%s",&peopleName[i]); // pass char * as argument to %s
should be -
scanf("%19s",peopleName[i]); // one space is left for null character
You can use malloc to allocate buffer dynamically.
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
char (*peopleName)[20];
int *peopleAge;
int i;
int maxAge=0, maxName=-1;
int dataNum;
printf("How many people? :");
if(scanf("%d",&dataNum)!=1)return 1;
peopleName=malloc(sizeof(char[20])*dataNum);
peopleAge=malloc(sizeof(int)*dataNum);
for(i=0;i<dataNum;i++)
{
printf("Name & Age %d :",i+1);
scanf("%s",peopleName[i]);
scanf("%d",&peopleAge[i]);
if(peopleAge[i]>maxAge)
{
maxAge=peopleAge[i];
maxName=i;
}
}
printf("%s %d", peopleName[maxName],peopleAge[maxName]);
free(peopleName);
free(peopleAge);
return 0;
}
Also please note that:
You should pass char*, not char(*)[20], for %s in scanf
peopleAge[maxAge] may be out of bounds. maxName (or other name but same role) should suit here.

Type errors when printing characters with printf

I'm trying to save a student's name in a char array and print the first student's name, but my code doesn't work. I'm practicing C, so I'm coding random programs by myself and need help with this one. My code generates the following error:
format '%s' expects argument of type 'char *', but argument 2 has type 'int'
I'm quite new to C. Can anyone help?
Code:
#include <stdio.h>
#include <string.h>
main(){
char StudentsName[100];
float StudentsGrades[100];
int NumStudents, i, j;
printf("How many students you want to process? ");
scanf("%d", &NumStudents);
if(NumStudents > 15){goto skip_lines_grades;}
for(i=0; i<NumStudents; i++){
printf("\n Write the name of the student: ");
scanf("%s", &StudentsName[i]);
}
//Prints First Student, I'M GETTING THE ERROR HERE, WHY?
printf("%s", StudentsName[0]);
goto skip_last_msg;
skip_lines_grades:;
printf("We can process 15 students for now, try again.");
skip_last_msg:;
}
I hope you got the basic idea from the discussion above. To summarize, you need to define an array of 100 character variables.
Also, regarding your error, for char StudentsName[100];, StudentsName[0] represents the first char variable value, not an address, as expected by %s. So, your compiler is right. If you need to print a char, you need to use %c specifier. However, that also is wrong, considering your program logic.
To correct, you can
allocate an array of char [100] type, to hold more than one student's data.
allocate memory dynamically.
loop over to take the input for each student.
print the output.
free the allocated memory.
check the modified code, its self-explanatory.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define NAMESIZ 128
int main(){
char *StudentsName[100]; //notice here
float StudentsGrades[100];
int NumStudents, i, j;
printf("How many students you want to process? ");
scanf("%d", &NumStudents);
if(NumStudents > 15){goto skip_lines_grades;}
for(i=0; i<NumStudents; i++){
StudentsName[i] = malloc(NAMESIZ); //notice here
printf("\n Write the name of the student: ");
scanf("%s", StudentsName[i]); //notice here
}
//for(i=0; i<NumStudents; i++) //uncomment to print all student data
i = 0; //comment out to print all student data
printf("Student [%d] is %s\n", (i+1), StudentsName[i]);
for(i=0; i<NumStudents; i++)
free (StudentsName[i]); //notice here
goto skip_last_msg;
skip_lines_grades:;
printf("We can process 15 students for now, try again.");
skip_last_msg:;
}

displaying numbers and strings from a structure in c

#include <stdio.h>
#include <string.h>
struct Directory {
char Name;
long int Number;
int HouseNumber;
char street;
};
int main(void)
{
struct Directory contact;
struct Directory *answer1, *answer2, *answer3, *answer4;
char answer;
printf("Welcome to Telephone Directory.\n\nPlease enter the name of the contact.\n");
scanf("%s", &contact.Name);
printf("Please enter the number of the contact.\n");
scanf("%ld", &contact.Number);
printf("Please enter the address of the contact.\n");
scanf("%d %s", &contact.HouseNumber, &contact.street);
answer1 = &contact;
answer2 = &contact;
answer3 = &contact;
answer4 = &contact;
printf("Would you like to obtain information on your contact? Enter 'yes' or 'no'.\n");
scanf("%s", &answer);
if (strcmp(&answer, "yes")==0) {
printf("%s\n", &answer1->Name);
printf("%ld\n", answer2->Number);
printf("%d", answer3->HouseNumber);
printf("%s", &answer4->street);
}
if (strcmp(&answer, "no")==0) {
printf("Thank you for using Telephone Directory.\n");
}
}
I'm trying to make a contacts program in C. I want the program to print the user's house address. I have the "HouseNumber" variable in the structure and the "street" variable in the structure, setting "answer3" as an int variable to display the "HouseNumber" and "answer4" as a char variable to display "street". Together, I was hoping they will print the user's address in a single string, but when I run the program and enter "yes" to display the contact information after entering the house number and street, the program crashes, and displays lldb with a bad thread error. It seems like everything is right, because my compiler says that there are no issues with the code, but it crashes. Can somebody please help me with this?
When you do scanf("%s", &answer);
You're writing the user's input into a char answer; The argument to scanf needs to have enough space to hold the entire string plus one null byte. Try something like:
char answer[256];
This assumes that input will never be more than 256 chars, but seems reasonable in a simple program like this. Note that gcc supports non-standard %a that will allocate a string for you if you pass in a char*.
When you try to store strings you need to ensure there's enough space for the data you're putting there, like in Dictionary only holding a char, or else you're going to overflow and stomp on some other memory you may need later.
The mistake i have observed in your code is, you have created name,street and answer variables as char but tried to store strings in them by using %s resulting into crashing. In those places either you have to use char * or character array.
char *name //(or) char name[15]
The modified code looks like this
#include <stdio.h>
struct Directory {
char Name[20];
long int Number;
int HouseNumber;
char street[20];
};
int main(int argc, char *argv[])
{
struct Directory contact;
struct Directory *answer1, *answer2, *answer3, *answer4;
char answer[4];
printf("Welcome to Telephone Directory.\n\nPlease enter the name of the contact.\n");
scanf("%s", contact.Name);
printf("Please enter the number of the contact.\n");
scanf("%ld", &contact.Number);
printf("Please enter the address and street of the contact.\n");
scanf("%d %s", &contact.HouseNumber, contact.street);
answer1 = &contact;
answer2 = &contact;
answer3 = &contact;
answer4 = &contact;
printf("Enter yes r no");
scanf("%s",answer);
if (strcmp(answer,"yes")==0) {
printf("%s\n", answer1->Name);
printf("%ld\n", answer2->Number);
printf("%d\n", answer3->HouseNumber);
printf("%s", answer4->street);
}
else {
printf("Thank you for using Telephone Directory.\n");
}
return 0;
}
struct Directory {
char * Name;
long int Number;
int HouseNumber;
char * street;
};
inside main:
struct Directory Contact;
Contact.Name = malloc(sizeof(char * sizeOfName));
scanf("%s", contact.Name);
Then you can copy in your Name/street etc.
Since Name is a char*, you won't use the address, but you'll just pass the pointer to scanf. This will fill that malloc'd memory with the string the user enters.

Resources