C Program - Don't know why it isn't working - c

The assignment is to create a program that lets the user enter student names and grades, list the input once all entries have been made, then calculate the average for all grades entered. The program uses structures and loops.
The code I have so far is below. It builds without any errors. However, after I enter the first set of "first name, last name, grade" and hit Enter, the program just sits there with a blinking cursor. I can't seem to figure out what I'm doing wrong.
#include <stdio.h>
#include <string.h>
#define MAX_LENGTH 50
// Structure to hold student names and grades
struct student
{
char firstName[MAX_LENGTH];
char lastName[MAX_LENGTH];
int grade;
};
int main ()
{
int i, j, num_students;
int sum = 0;
int cnt = 0;
// Determine how many students will be entered
printf ("Enter the number of students in your class: \n");
scanf ("%d", num_students);
// Obtain student names and grades
printf ("Enter first name, last name and grade separated by spaces. \n");
printf ("Enter END 0 when done entering information.\n\n");
struct student s[num_students];
for (i = 0; i < num_students; ++i) {
scanf ("%s %s %d", s[i].firstName, s[i].lastName, s[i].grade);
if(strcmp(s[i].firstName, "END") == 0) {
break;
}
}
// List students and grades entered
printf ("\nYou entered: \n");
for (j = 0; j < num_students; ++j){
if(strcmp(s[j].firstName, "END") == 0){
break;
}
printf("Name: %s %s, Grade: %d\n", s[i].firstName, s[i].lastName, s[i].grade);
}
// Calculate average of grades entered
for (i = 0; i < num_students; ++i)
{
if (strncmp(s[i].firstName, "END", 3) == 0){
break;
}
else {
sum += s[i].grade;
++cnt;
}
}
printf ("Average of Grades: %f\n", (float)sum/cnt);
return 0;
}

Change
printf("Name: %s %2, Grade: %d\n", s[i].firstName, s[i].lastName, &s[i].grade);
^ Wrong specifier ^ i should be j
to
printf("Name: %s %s, Grade: %d\n", s[j].firstName, s[j].lastName, s[j].grade);

Fix the '%2 bug and pass s[i].grade not &s[i].grade
This works for me: I added a line just after inserting the values for quick feedback
#include <stdio.h>
#include <string.h>
#define MAX_ENTRIES 20
#define MAX_LENGTH 50
// Structure to hold student names and grades
struct student
{
char firstName[MAX_LENGTH];
char lastName[MAX_LENGTH];
int grade;
};
int
main ()
{
int i, j;
int sum = 0;
int cnt = 0;
//Obtain student names and grades
printf ("Enter first name, last name and grade separated by spaces. \n");
printf ("Enter END 0 when done entering information.\n\n");
struct student s[MAX_ENTRIES];
for (i = 0; i < MAX_ENTRIES; ++i)
{
scanf ("%s %s %d", s[i].firstName, s[i].lastName, &s[i].grade);
printf ("Name: %s %s, Grade: %d\n", s[i].firstName, s[i].lastName,
s[i].grade);
if (strcmp (s[i].firstName, "END") == 0)
{
break;
}
}
//List students and grades entered
printf ("\nYou entered: \n");
for (j = 0; j < MAX_ENTRIES; ++j)
{
if (strcmp (s[j].firstName, "END") == 0)
{
break;
}
printf ("Name: %s %s, Grade: %d\n", s[j].firstName, s[j].lastName,
s[j].grade);
}
//Calculate average of grades entered
for (i = 0; i < MAX_ENTRIES; ++i)
{
if (strncmp (s[i].firstName, "END", 3) == 0)
{
break;
}
else
{
sum += s[i].grade;
++cnt;
}
}
printf ("Average of Grades: %f\n", (float) sum / cnt);
return 0;
}

Change this line (line no. 42)
printf("Name: %s %2, Grade: %d\n", s[i].firstName, s[i].lastName, &s[i].grade);
to this
printf("Name: %s %s, Grade: %d\n", s[j].firstName, s[j].lastName, s[j].grade);
I think it will help you :)

Append the code as ,
#include <stdio.h>
#include <string.h>
#define MAX_LENGTH 50
// Structure to hold student names and grades
struct student
{
char firstName[MAX_LENGTH];
char lastName[MAX_LENGTH];
int grade;
};
int main ()
{
int i, j, num_students;
int sum = 0;
int cnt = 0;
// Determine how many students will be entered
printf ("Enter the number of students in your class: \n");
scanf ("%d", &num_students);
// Obtain student names and grades
printf ("Enter first name, last name and grade separated by spaces. \n");
printf ("Enter END 0 when done entering information.\n\n");
struct student s[num_students];
for (i = 0; i < num_students; ++i) {
scanf ("%s %s %d", s[i].firstName, s[i].lastName, &s[i].grade);
if(strcmp(s[i].firstName, "END") == 0) {
break;
}
}
// List students and grades entered
printf ("\nYou entered: \n");
for (j = 0; j < num_students; ++j){
if(strcmp(s[j].firstName, "END") == 0){
break;
}
printf("Name: %s %s, Grade: %d\n", s[j].firstName, s[j].lastName, s[j].grade);
}
// Calculate average of grades entered
for (i = 0; i < num_students; ++i)
{
if (strncmp(s[i].firstName, "END", 3) == 0){
break;
}
else {
sum += s[i].grade;
++cnt;
}
}
printf ("Average of Grades: %f\n", (float)sum/cnt);
return 0;
}
Appended line 23 scanf ("%d", &num_students);
line 32 scanf ("%s %s %d", s[i].firstName, s[i].lastName, &s[i].grade);
line 46 printf("Name: %s %s, Grade: %d\n", s[j].firstName, s[j].lastName, s[j].grade);

Missed address operator in scanf argument twice:
scanf( "%d", &num_students );
/* .. */
scanf( "%s %s %d", s[i].firstName, s[i].lastName, & s[i].grade );
And index of previous loop was used instead of actual at printing array:
printf("Name: %s %s, Grade: %d\n", s[j].firstName, s[j].lastName, s[j].grade);
Handling "END"s is unneccessary when prompting for num_students. Just a suggestion: even loop variable names should be longer than a character. And feel free using double at floating point division unless you miss FPU.

Related

I am getting segmentation fault for this code in visual code arm64?

I am getting segmentation error?? PLS HElP
#include <stdio.h>
#include <string.h>
void display(char n2[], int x2[], char c1[], int p);
void display(char n2[], int x2[], char c1[], int p)
{
printf("Student Name : %s \n", n2[p]);
printf("Student Roll No : %d \n", x2[p]);
printf("Student Class : %s \n ", c1[p]);
}
int main()
{
char n[50], c[5], n1;
int y, x[8], x1;
int p1 = 0;
printf("Enter the number of students: \n");
scanf("%d", &y);
fflush(stdin);
for (int i = 0; i < y; i++)
{
fflush(stdin);
printf("Enter the Student Name : \n");
scanf("%s", n[i]);
fflush(stdin);
printf("Enter the Student Class : \n");
scanf(" %s", c[i]);
fflush(stdin);
printf("Enter the Student Roll No : \n");
scanf(" %d", &x[i]);
fflush(stdin);
}
fflush(stdin);
printf("Enter the Student Name and Roll Number :\n");
scanf("%s %d", &n1, &x1);
for (int i = 0; i < y; i++)
{
if ((n[i] == n1) && (x[i] == x1))
{
p1 = i;
}
else
{
printf("No Such Entry!!");
}
}
display(n, x, c, p1);
return 0;
}
The error occurs here:
scanf("%s",c[i]);
You are trying to store a string into a char (n[i]).
You should define n and the others as an array of strings instead of a string, for example:
char n[50][ 50 ], c[50][50], n1[50];
Also, you can't compare strings like you do on this line:
if ((n[i]== n1) && (x[i] == x1))
Use strcmp instead to compare strings.

Why can't I print all the character types of variables in array?

#include <stdio.h>
#include <conio.h>
int main() {
char name[20];
int age[20], i, size;
printf("Enter number of students: ");
scanf("%d", &size);
for (i = 0; i < size; i++)
{
printf("\nEnter Student # %d name: ", i+1 );
scanf("%s", &name[i]);
printf("\nEnter Student # %d age: ", i+1 );
scanf ("\n%d", &age[i]);
}
printf("---");
printf("\n Student Information");
for (i = 0; i < size; i++)
{
printf("\nStudent # %d :\n", i+1);
printf("Name: %c", name[i]); //how do i print the array here?
printf("\nAge: %d", age[i]);
}
return 0;
}
For some reason, I can't display the whole characters that are inputted, and instead, my program produces nothing. What's causing this and how can I fix it?
starboy_b already answered your question, but I want to highlight security issues in your code:
Keep in mind that using scanf to get input like you do is introducing dangerous vulnerabilities to your program.
Why? :
scanf does not know how much allocated space your variables have and does not prevent the user from entering more characters than your buffer can contain. This lead to buffer overflow and can be used to run attacker code.
Your better off e.g. using readline or fgets to get input from user.
#include <stdio.h>
#include <conio.h>
int main() {
char name[20][100];
int age[20], i, size;
printf("Enter number of students: ");
scanf("%d", &size);
for (i = 0; i < size; i++)
{
printf("\nEnter Student # %d name: ", i+1 );
scanf("%s", &name[i]);
printf("\nEnter Student # %d age: ", i+1 );
scanf ("\n%d", &age[i]);
}
printf("---");
printf("\n Student Information");
for (i = 0; i < size; i++)
{
printf("\nStudent # %d :\n", i+1);
printf("Name: %s", name[i]); //how do i print the array here?
printf("\nAge: %d", age[i]);
}
return 0;

Segmentaiton fault when function is called to input a double into a member of a array, previous input works

For a class assignment in C, I was tasked with writing a program that creates a struct with 4 members, first name, last name, hours, and payrate, after its created, it inputs the user to input the 4 members 3 times, so we have 3 employees. when the program is run, I can input the first and last and hours of the first employee but when it comes to input for the payrate this causes a segmentation fault. Here is my code
#include <stdio.h>
#include <stdlib.h>
#define SIZE 3
struct employee
{
char first[30];
char last[30];
double hours;
double payrate;
};
typedef struct employee emp;
int main(void)
{
system("clear");
emp emp[SIZE];
int counter;
for (counter = 0; counter < 3; counter++)
{
input(&emp[counter]);
}
for (counter = 0; counter < 3; counter++)
{
output(emp[counter]);
}
printf("%10s %10s %10s %10s", "First", "Last", "Hours", "Rate");
puts("------------------------");
for (counter = 0; counter < SIZE; counter++)
{
printf("%s %s %d %d \n", emp[30].first, emp[30].last, emp[10].hours, emp[10].payrate);
}
return 0;
}
void output(struct employee emp)
{
printf("First: %s \n", emp.first);
printf("Last: %s \n", emp.last);
printf("Hours: %d \n", emp.hours);
printf("Payrate: %d \n", emp.payrate);
puts("********************************");
}
void input(emp * ptr)
{
printf("Enter first name: ");
scanf("%s", ptr->first);
printf("Enter last name: ");
scanf("%s", ptr->last);
printf("Enter hours worked: ");
scanf("%d", ptr->hours);
printf("Enter payrate: ");
scanf("%d", ptr->payrate);
puts("********************************");
}
Edit#1 I edited some code and it works until the part of the table, it now works but gives out a 0.0000 in the first two colums of the table, here the edited code.
#include <stdio.h>
#include <stdlib.h>
#define SIZE 3
struct employee
{
char first[30];
char last[30];
double hours;
double payrate;
};
typedef struct employee emp;
int main(void)
{
system("clear");
emp emp[SIZE];
int counter;
for (counter = 0; counter < SIZE; counter++)
{
input(&emp[counter]);
}
for (counter = 0; counter < SIZE; counter++)
{
output(emp[counter]);
}
printf("%10s %10s %10s %10s", "First", "Last", "Hours", "Rate");
puts("\n ------------------------");
for (counter = 0; counter < SIZE; counter++)
{
printf("%s %s %lf %lf \n", emp[30].first, emp[30].last, emp[10].hours, emp[10].payrate);
}
return 0;
}
void output(struct employee emp)
{
printf("First: %s \n", emp.first);
printf("Last: %s \n", emp.last);
printf("Hours: %f \n", emp.hours);
printf("Payrate: %f \n", emp.payrate);
puts("********************************");
}
void input(emp * ptr)
{
printf("Enter first name: ");
scanf("%s", ptr->first);
printf("Enter last name: ");
scanf("%s", ptr->last);
printf("Enter hours worked: ");
scanf("%lf", &ptr->hours);
printf("Enter payrate: ");
scanf("%lf", &ptr->payrate);
puts("********************************");
}
The first problem is that the second argument to scanf should be a pointer. In the case of your strings, they are arrays and basically treated as pointers anyway so they work fine. You need to use the & operator to give it the address of the doubles. The next problem is that the conversion specifier "%d" is for signed integer conversion. For a double, use "%lf" since a double is a long float.
Example:
scanf("%lf", &ptr->hours);

Printing with structure

This is a program for preparing simple student marklist:
#include <stdio.h>
#include <conio.h>
#define SIZE 50
struct mark {
char name[50];
float marks[5];
};
int main() {
int sn, subn, i, j;
printf ("\n Enter Number of Students : ");
scanf ("%d",&sn);
printf ("\n");
struct mark n[SIZE];
for (i = 1; i < sn + 1; ++i){
printf (" Enter Name of Student %d : ",i);
scanf ("%s",&n[i - 1].name);
for (j = 1; j < 6; ++j){
printf (" Enter Marks of Subject %d : ",j);
scanf ("%f",&n[i - 1].marks[j - 1]);
}
}
printf ("\n\n ------------------------------------------------------------------- \n\n");
printf (" Student Name \t\t Sub 1\t Sub 2\t Sub 3\t Sub 4\t Sub 5");
printf ("\n --------------------------------------------------------------------\n");
for (i = 0; i < sn; ++i) {
printf ("\n %s \t\t ",n[i].name);
for (j = 0; j < subn; ++j){
printf ("%d \t",n[i].marks[j]); /* Problem with this line. Prints integers like -24611 etc.*/
}
}
getch();
return 0;
}
When I get to the marked line, the program prints some numbers like -241563 etc.
What's wrong? Is it something with the structure? First it prints five 0 when it would have printed the marks. And then prints the integers like -241563. Please help.
The format string in printf does not match the argument list
Change:
printf("%d \t", n[i].marks[j]);
to
printf("%f \t", n[i].marks[j]);

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;
}

Resources