I'm a student studying C, and seem to be stuck when using Structures and Arrays to read in characters as part of the array.
When I run the code, it skips over the char scanf and will not read in any characters. There is no problem reading in integers etc.
For example (This is an example, my code is much longer but I know there's a problem here). Is the scanf part that reads in the name correct?
struct stud s[5];
int i = 0;
for (int i = 0; i < 5; i++)
{
fflush(stdout);
s[i].no = i + 1;
printf("\nStud number %d\n", s[i].no);
printf("Enter name:");
scanf_s("%c", &s[i].name);
printf("Enter grade: ");
scanf_s("%d", &s[i].grade);
printf("Successfully added to grade book\n");
}
I declared them below:
struct stud {
int no;
char name;
int grade;
};
It would be great if someone could point me in the correct direction?
You have to declare name as a char array
struct room {
int no;
char name[32]; /* pick a reasonable size */
int grade;
};
And then this
scanf_s("%c",&s[i].name);
would change to
scanf_s("%s",s[i].name, _countof(s[i].name));
and since there is no guarantee that the name would be 31 characters length, you have to specify a field length like this
scanf_s("%31s",s[i].name, _countof(s[i].name));
the length should be the sizeOfArray - 1 since c strings need to mark the end of the string with a null byte '\0', and scanf_s will append that byte to the read string.
If you don't specify the field length and it turns out that there are more than characters than requested by _countof(s[i].name) then nothing is read, for more information read here.
Note that you should create a char array of a reasonable size and use %s as mentioned by #iharob in his answer if you want to enter more than 1 character for a student. If you want name to be a char,then change
scanf_s("%c", &s[i].name);
To
scanf_s(" %c", &s[i].name, 1);
The space before %c skips all kinds of blanks(like newlines and spaces) present in the stdin and %c will then scan a non-whitespace character.
The %c will not the characters because the characters will be present in stdin, and you have to skip the characters.
scanf_s("%c", &s[i].name);
if the last character in the previous is \n the %c will take the \n as input.
You have to change the code, just give a space before the %c.
scanf_s(" %c", &s[i].name);
This will flush the white space characters in the stdin and it will get the input.
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 want the output to print the data that we print. but it is not working as expected and the output is not displaying and it is exiting
#include <stdio.h>
int main() {
char name[20], department[3], section[1];
printf("enter the name of the student:");
scanf("%s", name);
printf("enter your department:");
scanf("%s", department);
printf("enter the section");
scanf("%s", section);
printf("Name:%s \n Department:%s \n Section: %s ", name, department, section);
return 0;
}
Your program has undefined behavior because the arrays are too short and scanf() stores the user input beyond the end of the arrays, especially the last one, section that can only contain an empty string which scanf() cannot read anyway.
Make the arrays larger and tell scanf() the maximum number of characters to store before the null terminator, ie: the size of the array minus 1.
Here is a modified version:
#include <stdio.h>
int main() {
char name[50], department[50], section[50];
printf("enter the name of the student:");
if (scanf("%49s", name) != 1)
return 1;
printf("enter your department:");
if (scanf("%49s", department) != 1)
return 1;
printf("enter the section");
if (scanf("%49s", section) != 1)
return 1;
printf("Name:%s\n Department:%s\n Section: %s\n", name, department, section);
return 0;
}
Note that using scanf with a %s conversion requires that each data item be a single word without embedded spaces. If you want name, department and section to accommodate spaces, which is more realistic for anyone besides Superman Krypton A, you would use %[\n] with an initial space to skip pending whitespace and newlines (or fgets() but in another chapter):
#include <stdio.h>
int main() {
char name[50], department[50], section[50];
printf("enter the name of the student:");
if (scanf(" %49[^\n]", name) != 1)
return 1;
printf("enter your department:");
if (scanf(" %49[^\n]", department) != 1)
return 1;
printf("enter the section");
if (scanf(" %49[^\n]", section) != 1)
return 1;
printf("Name:%s\n Department:%s\n Section: %s\n", name, department, section);
return 0;
}
scanf(" %49[^\n]", name) means skip any initial whitespace, including pending newlines from previous input, read and store and bytes read different from newline, up to a maximum of 49 bytes, append a null byte and return 1 for success, 0 for conversion failure or EOF is end of file is reached without storing any byte. For this particular call, conversion failure can happen if there is an encoding error in the currently selected locale.
The problem is that you have not accounted for the null character. It should work with the following.
char name[20] , department[4] , section[2];
The reason this happens is that C requires an extra character for the null character \0 which tells the program when the string ends.
first of all you should respect the size of string ,so you should either convert section to char or increase the size of that string because you have here the problem of '\0' character...so the rule is : the size of string is the size what you need + 1 for '\0' NULL character
and her is two program i tried to Modification you program for two scenarios :
#include <stdio.h>
int main(){
/// any size you like just respect the NULL character
char name[20],department[4],section[23];
printf("enter the name of the student:");
scanf("%s",name);
printf("enter your department:");
scanf("%s",department);
printf("enter the section");
scanf ("%s",section);
printf("Name:%s \n Department:%s \n Section:%s ", name,department,section);
return 0;
}
and case of char :
#include <stdio.h>
int main(){
char name[20],department[4];
char section;
printf("enter the name of the student:");
scanf("%s",name);
printf("enter your department:");
scanf("%s",department);
printf("enter the section");
///don't forget this space before %c it is important
scanf (" %c",§ion);
printf("Name:%s \n Department:%s \n Section:%c ", name,department,section);
return 0;
}
I watched for a long time and finally found the problem.
This is problem: char section[1];.
You declared the size is too short.
It looks like this after you declared it: section[0] = '\0';.
If you scanf a, the array data like section[0] = 'a';, and then it automatically add '\0' somewhere, so you got a memory leaking.
So replace char section[1]; to char section[2];.
I will not insist in the reasons of the other answers (that state other problems in your code than the one you are asking for) but I'll limit my answer to the reasons you don't get any output before the first prompt (there's no undefined behaviour before the third call of printf if you have input short enough strings to not overflow the arrays --- the last is impossible as long as you input one char, because to input one char you heed at least space for two)
I want the output to print the data that we print. but it is not working as expected and the output is not displaying and it is exiting
stdio works in linebuffer mode when output is directed to a terminal, which means that output is written to the terminal in the following cases:
The buffer is filled completely. This is not going to happen with a sort set of strings.
There is a \n in the output string (which there isn't, as you want the cursor to remain in the same line for input as the prompt string)
As there is no \n in your prompts, you need to make printf flush the buffer at each call (just before calling the input routines) You have two ways of doing this.
Calling explicitly the function fflush(3), as in the example below:
printf("enter the name of the student:");
fflush(stdout); /* <-- this forces flushing the buffer */
if (scanf(" %49[^\n]", name) != 1)
return 1;
configuring stdout so it doesn't use buffers at all, so every call to printf forces a write to the standard output.
setbuf(stdout, NULL); /* this disables buffering completely on stdout */
/* ... later, when you need to print something */
printf("enter the name of the student:"); /* data will be printed */
if (scanf(" %49[^\n]", name) != 1)
return 1;
But use this facilities only when it is necessary, as the throughput of the program is degraded if you disable the normal buffering of stdio.
So I have this code and for some reason when I am trying to enter all the "requested" information, my program always skips scanning the char
Currently I solved it by creating a char type variable with an array on 1 position and treating it as a string, but it doesn't make sense why it wont read a char
struct person
{
char name[30];
int age;
char sex;
};
int main()
{
struct person data[3];
for (i = 0 ; i < 3 ; i++)
{
printf("\nType in the data of the person number: %d",i+1);
printf("\nName: ");
scanf("%s",data[i].name);
printf("\nAge: ");
scanf("%d",&data[i].age);
printf("\nSex (M/F): ");
scanf("%c",data[i].sex);
}
}
It perfectly scans name and age, it even prints them, but for some reason, it refuses to scan the sex
The char gets read but it is the newline character '\n' left from the previous scanf(). To skip leading whitespace use
scanf(" %c", &data[i].sex);
// |
// +---- skips leading whitespace
And you also missed the address-of operator in your code.
The leading space is not necessary for most format specifiers like %d because they skip leading whitespace per default.
There is a newline character in your input stream, which is read as the character (%c) you're trying to read as gender.
You can read this character and ignore it in this way:
printf("\nSex (M/F): ");
getchar(); //ignore the remained character in input stream
scanf("%c", &data[i].sex);
As mentioned in other answers, you also have forgotten the reference symbol (&) in scanning the gender.
If I try to run this code then it doesn't ask me the value of s2.name. Why is it so?
#include<stdio.h>
int main()
{
struct student
{
char name;
int roll;
int age;
};
struct student s1;
struct student s2;
printf("Enter name of the student: ");
scanf("%c", &s1.name);
printf("%c", s1.name);
printf("\n");
printf("Enter name of the student: ");
scanf("%c", &s2.name);
printf("%c", s2.name);
return 0;
}
When you input a single character and press the Enter key, you are actually inputting two characters: The character in your input and a newline from the Enter key.
The second scanf reads this newline.
Or if you give multiple characters as input to the first name, then the second character will be read by the second scanf.
The way to solve the first problem is easy: Tell scanf to read and discard leading white-space (which newline is) by adding a single space in front of the format, like
scanf(" %c", &s2.name);
// ^
// Note space here
The way to solve the second problem is to read strings instead, which means you have to turn your name members into arrays and then use the "%s" format (preferably with a specified width so you don't read to many characters).
You are basically inputting two characters:
- the one that you type
- the newline character `\n` because you hit `enter`
A solution to this problem is clearing stdin after reading in the first "name":
#include<stdio.h>
int main()
{
struct student
{
char name;
int roll;
int age;
};
struct student s1;
struct student s2;
printf("Enter name of the student: ");
scanf("%c", &s1.name);
printf("%c", s1.name);
printf("\n");
fflush(stdin); //only works on windows, clears the input buffer
printf("Enter name of the student: ");
scanf("%c", &s2.name);
printf("%c", s2.name);
return 0;
}
Another way to clear the input buffer is:
while (getchar() != '\n');
This reads in all characters from the input buffer, because as soon as input is read by functions like getchar() or scanf(), the input is removed from stdin.
EDIT:
When you input values using getchar(), scanf(), etc., then the symbols that you type into stdin (most of the times via a keyboard) are stored in the input buffer at first (stdin). getchar() or any similar function then takes the values that it should read in, out of the input buffer. For example:
scanf("%d", &var);
scanf("%d", &var2);
If I input 5x, the characters in the input buffer are '5', 'x' and \n (because you hit the enter key). The first scanf() then takes out the '5', as it fits the format string %d. After that, the characters in the input buffer are 'x' and \n. In this case scanf returns 1, because it read in one value correctly.
When it then continues to the second one, scanf() won't even let you type anything, as there is already something in the input buffer stdin. It won't store any data however, because the first "item" in stdin ist 'x'. That doesn't fit the format string %d. The compiler then doesn't continue to read. In this case scanf would return 0, as no value was read in correctly.
i am a learner of 'C' and written a code, but after i compile it, shows a Debug Error message, here is the code:
#include<stdio.h>
void main()
{
int n,i=1;
char c;
printf("Enter Charecter:\t");
scanf("%s",&c);
printf("Repeat Time\t");
scanf("%d",&n);
n=n;
while (i <= n)
{
printf("%c",c);
i++;
}
}
Pls tell me why this happens and how to solve it
The scanf("%s", &c) is writing to memory it should not as c is a single char but "%s" expects its argument to be an array. As scanf() appends a null character it will at the very least write two char to c (the char read from stdin plus the null terminator), which is one too many.
Use a char[] and restrict the number of char written by scanf():
char data[10];
scanf("%9s", data);
and use printf("%s", data); instead of %c or use "%c" as the format specifier in scanf().
Always check the return value of scanf(), which is the number of successful assignments, to ensure subsequent code is not processing stale or uninitialized variables:
if (1 == scanf("%d", &n))
{
/* 'n' assigned. 'n = n;' is unrequired. */
}
scanf("%s",&c); should be scanf("%c",&c);
The %s format specifier tells scanf you're passing a char array. You're passing a single char so need to use %c instead.
Your current code will behave unpredictably because scanf will try to write an arbitrarily long word followed by a nul terminator to the address you provided. This address has memory allocated (on the stack) for a single char so you end up over-writing memory that may be used by other parts of your program (say for other local variables).
I'm not sure you understood the answer to your other question: Odd loop does not work using %c
These format specifiers are each used for a specific job.
If you want to get a:
character from stdin use %c.
string (a bunch of characters) use %s.
integer use %d.
This code:
char c;
printf("Enter Character:\t");
scanf("%c",&c);
Will read 1 character from stdin and will leave a newline ('\n') character there. So let's say the user entered the letter A in the stdin buffer you have:
A\n
The scanf() will pull 'A' and store it in your char c and will leave the newline character. Next it will ask for your int and the user might input 5. stdin now has:
\n5
The scanf() will take 5 and place it in int n. If you want to consume that '\n' there are a number of options, one would be:
char c;
printf("Enter Character:\t");
scanf("%c",&c); // This gets the 'A' and stores it in c
getchar(); // This gets the \n and trashes it
Here is a working version of your code. Please see inline comments in code for fixes:
#include<stdio.h>
void main()
{
int n,i=1;
char c;
printf("Enter Character:\t");
scanf("%c",&c);//Use %c instead of %s
printf("Repeat Time\t");
scanf("%d",&n);
n=n;//SUGGESTION:This line is not necessary. When you do scanf on 'n' you store the value in 'n'
while (i <= n)//COMMENT:Appears you want to print the same character n times?
{
printf("%c",c);
i++;
}
return;//Just a good practice
}