scanf function is skipping input in for loop in C Programming - c

I have write simple code using structure method and in that code I am taking string(name) as input using for loop for 3 students. For 1st iteration each line in for loop is working as it should be.... but problem comes on second iteration... in second iteration scanf is skipping input for string (name)...
My code is as below :
#include<stdio.h>
struct student_data
{
char name[5];
int dsd;
int dic;
int total;
};
void main()
{
struct student_data s[3];
int i;
for(i = 0;i<3;i++)
{
printf("Enter Name of Student\n");
scanf("%[^\n]",s[i].name); // Problem occures here in
// second iteration
printf("\nEnter marks of DSD\n");
scanf("%d",&s[i].dsd);
printf("Enter marks of DIC\n");
scanf("%d",&s[i].dic);
s[i].total = s[i].dsd+s[i].dic;
}
printf("%-10s %7s %7s %7s\n ","Name","DSD","DIC","Total");
for(i=0;i<3;i++)
{
printf("%-10s %5d %6d %6d\n",s[i].name,s[i].dsd,s[i].dic,s[i].total);
}
}

The main problem with your code was that you defined the student_data s[2] which is a array of size two, but in the loop, you are looping for (i=0; i<3; i++) which is valid for an array of size 3. This small modifications will work fine:
int main()
{
struct student_data s[2]; // array of size 2
int i;
for(i=0; i<2; i++) // i will have values 0 and 1 which is 2 (same as size of your array)
{
printf("Enter Name of Student\n");
scanf("%s", s[i].name);
printf("\nEnter marks of DSD\n");
scanf("%d", &s[i].dsd);
printf("Enter marks of DIC\n");
scanf("%d", &s[i].dic);
s[i].total = s[i].dsd+s[i].dic;
}
printf("%-10s %7s %7s %7s\n ","Name","DSD","DIC","Total");
for(i=0; i<2; i++) // same mistake was repeated here
{
printf("%-10s %5d %6d %6d\n",s[i].name,s[i].dsd,s[i].dic,s[i].total);
}
return 0;
}

Related

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

Can't read array of structure in C

I am trying to read members of an object like in the code below.
The issue is that the code can't read the second member (car[i].model) in the array and the third one (car[i].price), only the first one (car[i].manufacturer).
#include <stdio.h>
#include <conio.h>
struct machine
{
int price;
char manufacturer[30];
char model[30];
};
int main()
{
int i = 0, n;
printf("Introduce number of cars: ");
scanf_s("%d", &n);
struct machine car[100];
for (i = 0; i < n; i++)
{
printf("Data of the car nr. %d:\n", i+1);
printf("Manufacturer: ");
scanf_s("%s", car[i].manufacturer);
printf("Model: ");
scanf_s("%s", car[i].model); printf("\n");
printf("Price: ");
scanf_s("%d", &car[i].price); printf("\n");
}
for (i = 0; i < n; i++)
{
printf("Data of the car nr. %d:\n", i + 1);
printf("Manufacturer: %s\n", car[i].manufacturer);
printf("Manufacturer: %s\n", car[i].manufacturer);
printf("Model: %s\n", car[i].model);
printf("Price %d\n", car[i].price);
}
_getch();
}
scanf_s requires the buffer size to be specified for input parameters with format %s. The buffer size includes the terminating null. Adapt your code like this:
struct machine
{
int price;
char manufacturer[30];
char model[30];
};
struct machine car[100];
....
scanf_s("%s", car[i].manufacturer, 30 );
// ^^ buffer size
....
scanf_s("%s", car[i].model, 30 );
// ^^ buffer size
....
scanf_s("%d", &car[i].price); // no buffer size

Reading and printing strings in C

I want to scan and print two strings one after another in a loop.But I cannot do it.Only one string gets scanned and printed if i use the loop.If i try to print without the loop then the two "gets()" work properly.
#include <stdio.h>
int main()
{
int T,i,j;
char name1[100];
char name2[100];
scanf("%d",&T);
for(i=0; i<T; i++)
{
printf("Case %d: ",i+1);
//scanf("%[^\n]s",name1);
gets(name1);
/*for(j=0; j<strlen(name1); j++)
{
printf("%c",name1[j]);
}*/
puts(name1);
//scanf("%[^\n]s",name2);
gets(name2);
/*for(j=0; j<strlen(name2); j++)
{
printf("%c",name2[j]);
}*/
puts(name2);
}
}
Here you go. Use fflush(stdin). It will take two inputs and print them one after the another.
#include<stdio.h>
int main()
{
int T,i,j;
char name1[100];
char name2[100];
scanf("%d",&T);
for(i=0; i<T; i++)
{
printf("Case %d: ",i+1);
fflush(stdin);
gets(name1);
gets(name2);
puts(name1);
puts(name2);
}
return 0;
}
Edit: As suggested in the comment below, using gets() is not advisable if you do not know the number of characters you wish to read.
After taking testcase from the user, next line gets() function will take the '\n' you have to ignore the scenario.
Here's a tricky solution of this problem. Just use '\n' after %d in scanf function. scanf("%d\n",&T);
#include <stdio.h>
int main(void) {
char s1[100],s2[100];
int i,T;
scanf("%d\n",&T);
for(i = 0; i < T; i++){
printf("Case %d: ",i+1);
gets(s1);
puts(s1);
gets(s2);
puts(s2);
}
return 0;
}
You do not terminate your prints.
stdout is buffered.
Print is only performed after a "\n" or explicit flush.
try something around the lines:
#include <stdio.h>
int main()
{
int T,i,j;
char name1[100];
char name2[100];
scanf("%d",&T);
for(i=0; i<T; i++)
{
#ifdef BAD_CODE
printf("Case %d: ",i+1);
gets(name1);
puts(name1);
gets(name2);
puts(name2);
putchar("\n");
#else //better code
fgets(name1, sizeof(name1)-1, stdin);
fgets(name2, sizeof(name2)-1, stdin);
printf("Case %d: '%s' '%s'\n",i+1, name1, name2);
#endif
}
}

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