C program not printing the string that is given as input - 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",&section);
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.

Related

why %s does not print the string after it encounters a space character? [duplicate]

This question already has answers here:
How do you allow spaces to be entered using scanf?
(11 answers)
Closed 6 years ago.
#include <stdio.h>
int main()
{
char name[20];
printf("Enter name: ");
scanf("%s", name);
printf("Your name is %s.", name);
return 0;
}
Output:
Enter name: Dennis Ritchie
Your name is Dennis.
So far I haven't found any specific valid reason for this question. Can anyone help me out?
scanf only read till it gets to space that is why it is not storing after the first space , so your printf function is not faulty , it is the scanf that is not storing the complete string , stopping on encountering first space.
One should never use gets() , unless they completely know what they are doing , because it does not have buffer overflow protection , it continue to read after the buffer ends until it finds a new line or encounter a EOF. You can read more about that here.Please Check This Why is the gets function so dangerous that it should not be used?
You should instead use fgets().
#include <stdio.h>
int main(){
char name[20];
printf("Enter name: ");
fgets(name,20,stdin);
printf("Your name is %s.", name);
return 0;
}
Remember fgets() also reads newline character(the one you get when you press enter) so you should manually remove that.
Also I highly Recommend this answer for using fgets() to its full potential and avoiding common pitfalls.
This answer tells about using scanf to read string.What it says is the following:
int main(){
char string[100], c;
int i;
printf("Enter the string: ");
scanf("%s", string);
i = strlen(string); // length of user input till first space
do{
scanf("%c", &c);
string[i++] = c; // reading characters after first space (including it)
}while (c != '\n'); // until user hits Enter
string[i - 1] = 0; // string terminating
return 0;
}
How this works? When user inputs characters from standard input, they will be stored in string variable until first blank space. After that, rest of entry will remain in input stream, and wait for next scanf. Next, we have a for loop that takes char by char from input stream (till \n) and appends them to end of string variable, thus forming a complete string same as user input from keyboard.

Delete last character of a string

why doesn't this code work?
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
#include<string.h>
int main(void)
{
// local declarations
int len;
char* pStr;
// statements
printf(" how many characters you want to enter?\n");
scanf("%d", &len);
pStr=(char*)calloc(len+1,sizeof(char));
printf("\n enter your string: ");
gets(pStr);
*(pStr+len)='\0';
printf("\n your string: ");
puts(pStr);
printf(" oops! last character deleted.");
getch();
return 0;
}
although it runs correct, when i use scanf function to read the string, but
why it does not with gets?
scanf("%s", pStr) skips to the first non-whitespace character while gets doesn't.
After the first scanf the trailing newline is still in the input buffer so that when you call gets the result is an empty line unless you entered extra characters after the number.
Note that gets is marked as obsolete due to serious security flaws.
It is recommended that any use of gets(var) is replaced with fgets(var, length, stdin).
Because arrays are zero based, and (assuming the input is valid and the correct length, assumption which your code ought not to make) *(ptr + len) already contains \0 and you are just overwriting it. You meant to overwrite ptr[len-1]

Get a space in a multidimensional array

I am trying to get a name in an array " char name[100][100]". I tried doing many thing like these, but none work.Can you help me?
The code: Its a simple student's grade system i think, but only prints "" when trying to save a name.
#include <stdio.h>
#include <string.h>
void insert();
char name[100][100];float f[20];int z;
int main()
{
int x=0;
do{
printf("<1> Insert student\n");
printf("=> ");
scanf("%d",&x);
printf("\n*************************************************************\n");
switch(x){
case 1:
insert();
break;
default: printf("NO");
break;
}
}while(insert >=0 );
return 0;
}
void insert()
{
int x;
int y=0;
float n1,n2,p;
printf("How many students?: ");
scanf("%d",&y);
for(x=0;x<y;x++){
printf("Insert name: ");
fgets(name[x], 100, stdin);
int len = strlen(name[x]);
if (name[x][len-1] == '\n') {
name[x][len-1] = '\0';
}
printf("name[%d] = \"%s\"\n", x, name[x]);
printf("Insert first grade: ");
scanf("%f",&n1);
printf("Insert second grade: ");
scanf("%f",&n2);
printf("Insert final grade: ");
scanf("%f",&p);
f[x] = (n1 * 0.3)+(n2 * 0.3)+(p * 0.4);
z++;
}
for(x=0;x<z;x++){
if(f[x] < 6){
printf("the final grade of %s is: %.2f \n",name[x], f[x]);}
else{printf("the final grade de %s es: %.2f \n",name[x], f[x]);}
}
}
You should bear in mind that fgets() returns the new-line as well, if there's enough space in the buffer. You might want to take it out:
#include <stdio.h>
#include <string.h>
int main()
{
char name[100][100];
int y = 5;
int x = 0;
for (x = 0; x < y; x++) {
printf("Insert name: ");
fgets(name[x], 100, stdin);
int len = strlen(name[x]);
if (name[x][len-1] == '\n') {
name[x][len-1] = '\0';
}
printf("name[%d] = \"%s\"\n", x, name[x]);
}
}
Why are you using that %[^\t\n] string format? You should just go with a %s string format if you want to read a string (or, better, a %100s to limit the number of characters read).
scanf("%100s",name[x]) works just fine, but will mess things up when you try to use spaces (i.e. the scanf() will read one word at a time).
To avoid that, you can use the second option, that is fgets(). But, in this case, you need to pay attention to the final \n character that is appended to the string. To prevent the newline character from ending your string, you can simply do the following:
name[x][strlen(name[x])-1] = 0;
The previous code simply replaces the \n character with a null byte, thus ending the string and "ignoring" the newline.
EDIT:
The thing you need to understand is that the standard input (i.e. the keyboard input usually) is handled as if it were a file (in fact, you can use functions like fgets(), as if you were reading a normal file). So, as it happens with normal files, each line ends with a special character, \n. Every time you enter an input, and you press "Enter", a newline character is appended to your input.
There's a couple of things you need to know to understand what it is that you're doing wrong:
Some functions (like fgets()) read a line until a newline character is found. The newline character is also read, and returned in the string that was just read.
Other functions (like scanf()) also read lines until some special characters (such as or \n) are found. But, in this case, the final character is not read.
And, last: every time you open a file, the process keeps count of the number of characters you have read from the beginning of the file (or, to put it in an easier (and more correct) way, it "stores" a "pointer" to the next character that should be read).
With this being said, let's have a look at what happens with your program: first, the number of students is read (using scanf()), and, then, a name is read (using fgets()).
So, your input "file", looks like:
4\n
^
John Smith\n
...
The ^ is a pointer to the next character that should be read (and isn't, obviously, part of the input).
After the scanf() (which, as I mentioned, won't read the \n), the situation will be the following:
4\n
^
John Smith\n
...
Now, when you read the next line using fgets(), the "pointer" is already pointing to a newline character, and will therefore assume (correctly!) that the line has ended. The string you are reading is therefore "\n", instead of "John Smith\n".
The easiest way to fix this problem is to read, after every scanf(), single characters from standard input until a newline character is encountered.
scanf ( ... );
while (getc(stdin)!='\n');
Usually reading a single character should be enough, but in some cases (e.g. 4 \n) a single getc() isn't effective.
Basically, whenever a character is read from the file, the "pointer" is updated.
I really hope this cleared things up a bit. It isn't that easy to understand these details at first but, as you get more experience, things will definitely become clearer!

Trouble using char in scanf in a structure

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.

Getting Debug Error in C

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
}

Resources