I'm new in C. I'm trying to make an addStudent() function like this:
I'm currently stuck on 2 issues:
No matter what I have entered, the object's name, mid, and final are still empty or zero.
If I change the name parameter to *name, it only takes the first character. ie, if "James" is entered, it only takes "J".
UPDATE: I firstly thought it was scanf's problem, but even when I removed it and initialized the variables, the object std is still empty. I was still wondering what is the correct way to pass arguments to a new object, like this example.
void addStudent(struct Student array[SIZE], int *currentSize){
char name[20];
int mid, final;
printf("Enter name: ");
scanf("%s", name);
printf("Enter midterm grade: ");
scanf("%d", &mid);
printf("Enter final grade: ");
scanf("%d", &final);
struct Student std = {*name, mid, final};
array[0] = std;
++*currentSize;
}
Student structure:
struct Student{
char name[20];
int midterm;
int final;
};
FIXED:
If I directly passed the variables to scanf, everything works fine.
void addStudent(struct Student array[], int *currentSize){
printf("Enter name: ");
scanf("%s", array[*currentSize].name);
printf("Enter midterm grade: ");
scanf("%d", &array[*currentSize].midterm);
printf("Enter final grade: ");
scanf("%d", &array[*currentSize].final);
++*currentSize;
}
%s format specifier with scanf() reads space-delimited input. In other words, it cannot read a "complete" input which contains white-space.
Quoting C11, chapter 7.21.6.2
s
Matches a sequence of non-white-space characters. [....]
You should use fgets() to read the input and then process it.
That said, changing the argument to %s to *name is not correct anyways, as it creates mismatch between the expected (pointer to character array) and the actual (character) - creating undefined behaviour.
Related
My issue is coming from the %c name input, I am getting an error that it is expecting type char * but has type char * [15] for the scanf function. I am also getting an error in the printf where the %c expects int but has type char *. I am still quite new at this so if it could be explained as simply as possible that would be amazing.
#include <stdio.h>
struct Student {
int StudentID;
char Name[15];
float Mark1;
float Mark2;
float Mark3;
} a;
int main() {
float ave;
printf("Please input Student's ID \n");
scanf("%d", &a.StudentID);
printf("Please input Student's name. \n");
scanf(" %c", &a.Name);
printf("Input Mark 1. \n");
scanf("%f", &a.Mark1);
printf("Input Mark 2. \n");
scanf("%f", &a.Mark2);
printf("Input Mark 3. \n");
scanf("%f", &a.Mark3);
ave = (a.Mark1 + a.Mark2 + a.Mark3) / 3;
printf("Student Detail\nStudent ID: %d\nName: %c\nMark 1: %.2f\n Mark 2: %.2f\n Mark 3: %.2f\nAverage: %.2f\n",
a.StudentID, a.Name, a.Mark1, a.Mark2, a.Mark3, ave);
return 0;
}
Your problem is related to the difference between an array of chars and a single char.
The %c format only reads in one character at a time.
If you wish to read a string of characters use %s and it will read until a whitespace. (Please make sure you don't try to read a name more than 14 characters long into your 15 character buffer)
In more depth, your char Name[15] is actually a pointer to a series of chars in memory. You are accidentally trying to change to pointer itself, instead of the chars that it points to. This is why the compiler expects a char * .
Instead if you truly meant to only read one char you could use
scanf(" %c", &a.Name[0]);
to place the character in the first block of the Name array.
If this is too complicated don't worry, it will all come eventually :)
For now I think %s will suffice.
You can use %14s to be extra safe.
Also don't forget to use %s in the final printf as well
In your scanf() call, %c tells scanf() to accept a single character. But your argument is a character array. C is a low-level language; it's not smart enough to realize you wanted a string (char array) as input. You have to tell it by using %s instead of %c.
I'm having a bit of trouble passing multiple variables to scanf:
#include<stdio.h>
int main(void) {
char *name;
float weight;
printf("Please enter your name, then weight separated by a comma: ");
scanf("%s,%f", name, &weight);
printf("%s, your weight is %.2f!\n", name, weight);
return 0;
}
Please enter your name, then weight separated by a comma: Tommy,184
Tommy,184, your weight is 0.00!
What would be the proper way to do this, and why doesn't scanf detect the comma and pull the necessary values in their variables?
There are two mistakes in your code:
Wild pointer
char *name; is not a safe code. *name* is a wild pointer and it points to some arbitrary memory location and may cause a program to crash or behave badly. You should use an array like char name[10]. You can refer to this link.
Comma in scanf
You can check this thread for more details
The comma is not considered a whitespace character so the format specifier "%s" will consume the , and everything else on the line writing beyond the bounds of the array sem causing undefined behaviour
I've just tried to modify your code, you should consider removing the comma, and replace it with a space
printf("Please enter your name, then weight separated by a space: ");
scanf("%s %f", name, &weight); // your code should work properly
I think you should be using a char array for the name variable and if you want to store its adress you would assign it to a pointer, doesn't make sense the way you wrote it
float weight;
char[20] name;
scanf(" %s, %f", &name, &weight);
Can you give this a try?
int main()
{
int num;
char str[50];
scanf("%49[^,],%d", str, &num);
printf("%s %d",str, num);
return 0;
}
EDIT
Explanation:
We can read input up to a specific character/characters using %[^<Your character(s)>]. The number 49 here simply refers to the length of string you'd receive and the last character is a null. Adding specific length is up to you ;) This is just one example of getting input the way you asked.
i have this code
#include<stdio.h>
#include<stdlib.h>
void main()
{
char firstName[99], middleName[99], lastName[99];
int hourPay[99], hourWeek[99], taxRate[99], grossSal[99], taxDed[99], netSal[99];
printf("Enter your first name:");
scanf("%s", &firstName);
printf("Enter your middle initial:");
scanf("%s", &middleName);
printf("Enter your last name:");
scanf("%s", &lastName);
printf("Enter your hourly rate of pay:\n");
scanf("%d", &hourPay);
printf("Enter hours worked per week:\n");
scanf("%d", &hourWeek);
printf("Enter your tax rate:");
scanf("%d", taxRate);
grossSal = hourPay * hourWeek;
printf("%d", grossSal);
system("pause");
}
Everything was working fine till i got to line 21, i added in the "int" line after it stopped running to try and differentiate the text inputs from the number inputs but that didnt help,and i am stuck language is C
Your int variables are actually arrays of int, and it doesn't make sense to do multiplication on arrays.
Change your definitions to:
int hourPay, hourWeek, taxRate, grossSal, taxDed, netSal;
And change this:
scanf("%d", taxRate);
To this:
scanf("%d", &taxRate);
Also, you should remove the & when reading in strings, since the %s format specifier expects a char * (which char array decays to) and not a pointer to an array which is what you're passing in now.
You are declaring int arrays by doing int hourPay[99]. If you are only taking one input from the user, remove the [99] from the ints. Then it should work. If you are taking multiple inputs of each variable, you'll have to reference a specific member in the array you want to use.
So I have this code which is reading in strings and applying them to their respective struct members fine, but as soon as I get into reading an int, my program crashes and returns a segfault. However if I assign a variable a value, then pass that value into the struct, it works fine. If I assign a variable a value, overwrite that value with a scanf, then pass it into the struct, it segfaults again.
void createcompetitor() {
struct competitor *newcompetitor = malloc(sizeof (struct competitor));
if (newcompetitor == NULL)
return;
printf("Please enter the competitor's first name\n");
fgets(newcompetitor->firstname, 25, stdin);
printf(newcompetitor->firstname);
printf("Please enter the competitor's last name\n");
fgets(newcompetitor->lastname, 35, stdin);
printf(newcompetitor->lastname);
printf("Please enter the competitor's address\n");
fgets(newcompetitor->address, 105, stdin);
printf(newcompetitor->address);
printf("Please enter the competitor's age\n");
scanf("%d", &newcompetitor->phonenumber);
scanf("%c");
printf("%d", newcompetitor->age);
printf("Please enter the competitor's phone number\n");
scanf("%d", &newcompetitor->phonenumber);
scanf("%c");
printf("%d", newcompetitor->phonenumber);
printf("Please enter the competitor's registration number\n");
scanf("%d", &newcompetitor->competitornumber);
scanf("%c");
printf("%d", newcompetitor->competitornumber);
}
Sorry for super messy code, I'm just trying to figure out what exactly is going on with the program.
EDIT:
The struct definition is
struct competitor {
char firstname[20];
char lastname[30];
char address [100];
int age;
int phonenumber;
int competitornumber;
struct competitor *next;
};
Note that mismatch
char firstname[20];
And
fgets(newcompetitor->firstname, 25, stdin);
You allow writing to outside of the array boundaries, that's undefined behavior.
scanf("%c"); is another culprit.
scanf reads input from stdin and attempts to write it to the address it was passed for the parameter, but you didn't pass any address!
The behavior of your entire program is undefined. Be thankful it only crashed.
If you intend to wait for user interaction before continuing, specify in the format to scnaf that the character should be read, but not written anywhere. Like this:
`scanf("%*c");`
This however is a brittle "waiting for user interaction" technique. So bear that in mind.
Your segfault is most probably caused by
printf(newcompetitor->firstname);
printf() should be used like this:
printf("%s\n", newcompetitor->firstname);
You can use it with one argument if and only if you just have a string literal with no variables, otherwise you need to provide both format string and proper number of variable names.
i create a really simple coding and it got no errors but when it run, i cant put input in the 'age' side.
#include <stdio.h>
#include <conio.h>
struct baby
{
char name[2][30];
char sex[2][7];
char birthday[2][12];
};
struct parents
{
char nama[2][30];
int age[2];
};
struct momdad
{
struct parents father;
struct parents mother;
};
struct momdad info;
struct baby newborn;
int main()
{
int i;
for(i=0;i<2;i++)
{
printf("\nEnter baby's name %d: ",i+1);
gets(newborn.name[i]);
printf("Enter baby's sex %d (Female/Male): ",i+1);
gets(newborn.sex[i]);
printf("Enter baby's birthday %d (dd/mm/yyyy): ",i+1);
gets(newborn.birthday[i]);
printf("Enter father's name %d: ",i+1);
gets(info.father.nama[i]);
printf("Enter father's age %d: ",i+1);
gets(info.father.age[i]);
printf("Enter mother's name %d: ",i+1);
gets(info.mother.nama[i]);
printf("Enter mother's age %d: ",i+1);
gets(info.mother.age[i]);
}
printf("\n\n\tNEW BORN BABY IN KUANTAN HOSPITAL");
printf("\n\n===============================================");
for(i=0;i<2;i++)
{
printf("\n\nBaby name: %s",newborn.name[i]);
printf("\nSex: %s",newborn.sex[i]);
printf("\nBirthday: %s",newborn.birthday[i]);
printf("\n\nFather name: %s",info.father.nama[i]);
printf("\nFather age: %s",info.father.age[i]);
printf("\n\nMother name: %s",info.mother.nama[i]);
printf("\nMother age: %s",info.mother.age[i]);
printf("\n\n----------------------------------------------");
}
getch();
}
this is my declaration that i think is wrong but i dont know how.
int age[2];
and the input will be putting in here
printf("Enter father's age %d: ",i+1);
gets(info.father.age[i]);
n in here
printf("Enter mother's age %d: ",i+1);
gets(info.mother.age[i]);
i'm still new in programming sorry for asking this simple question
Never use gets(). It cannot be used safely, and as of 2011 it's been removed from the language.
In a comment, you mention calling fflush(stdin);. The behavior of fflush is undefined for input streams. Some implementations define the behavior, but depending on that will make your program non-portable -- and you don't need it anyway.
The simplest way to read input data is to use scanf(), but that has some of its own problems. For example, if you use scanf("%d", &n); and type 123, it will consume the 123 and leave anything following it (such as a newline) waiting to be read.
A better way to read input is to use fgets to read a line of text, then sscanf to parse the data from the input line. It re
Here's an example:
#define MAX_LEN 200
char line[MAX_LEN];
int num;
printf("Enter an integer: ");
fflush(stdout);
if (fgets(line, MAX_LEN, stdin) == NULL) {
fprintf(stderr, "Error reading line\n");
exit(EXIT_FAILURE);
}
if (sscanf(line, "%d", &num) != 1) {
fprintf(stderr, "Error parsing integer from line\n");
exit(EXIT_FAILURE);
}
printf("The number is %d\n", num);
I call fflush(stdout) after the first printf to ensure that the prompt actually appears. stdout can be line-buffered, meaning that output won't appear until you've printed an entire line. The fflush isn't always necessary, but it's a good idea.
The fgets call reads a full line of input or MAX_LEN characters if the line is longer than that. (gets has no way to specify the maximum input size, so no matter how big your target array is, it can always read more and clobber random memory.) fgets returns a null pointer if there was a problem, and I check for that.
sscanf is similar to scanf, but it reads data from a string in memory, not from standard input. (There's also fscanf, which reads from a specified file.) It returns the number of items that it successfully scanned, so a value other than 1 would indicate an error.
I suggest reading the documentation for all these functions; I haven't covered everything they do. In fact, you should read the documentation for any standard library function you use.