I am unable to put the value in the first element of the array. It's always asking to put the value in array second element.
#include<stdio.h>
#include<string.h>
int main(void)
{
int a, i;
char names[50][50];
printf("\nEnter the number of names you want :");
scanf("%d", &a);
for(i = 0; i < a; i++)
{
printf("\n%d name :", i);
gets(names[i]);
}
printf("\nThe required name lists :");
for(int i = 0; i < a; i++)
{
printf("\n%d name :", i+1);
puts(names[i]);
}
return 0;
}
As scanf leaves behind a dangling newline character \n it causes the gets(Use fgets) to not wait for the input from the user. Try flushing the input buffer by using getchar.
Update: Added mechanism to remove the trailing \n registered by the fgets
#include<stdio.h>
#include<string.h>
int main()
{
int a,i;
printf("Enter the number of names you want: ");
scanf("%d",&a);
//Flush the input buffer
int ch;
while ((ch = getchar()) != '\n' && ch != EOF);
char names[50][50];
for(i=0;i<a;i++)
{
printf("%d name: ",i);
fgets(names[i],50,stdin); //Use fgets instead of gets
// To remove th \n registed by the fgets
char *p;
if ((p = strchr(names[i], '\n')) != NULL)
*p = '\0';
}
printf("The required name lists: \n");
for(int i=0;i<a;i++)
{
printf("%d name: ",i+1);
puts(names[i]);
}
return 0;
}
Reference:
Remove newline skipped by scanf
Remove newline registered by fgets
Put this after line scanf("%d",&a), as a workaround,
char c;
scanf("%c",&c);
Also use fgets(names[i],50,stdin) instead of gets(names[i])
Note: You get warning when you use gets in your code, as it is always assumes a consistent input from user. More explanation over here
Why is the gets function so dangerous that it should not be used?
Related
I want to write a program, at first I input a number N, then I want to get the name (can consist of multiple words) and price of N items one by one. Example:
3
item a // the name can consist of multiple words
25.00
item b
12.50
item c
8.12
Next I want to process this data, however i got stuck on the scanning part. my code looks like this:
#include <stdio.h>
int main(){
int n;
char name[50];
int price;
scanf("%d\n", &n);
for(int i = 0; i < n; i++){
scanf("%s\n%d",name,&price);
printf("%s , %d", name, price);
}
printf("end");
}
This works for a single word item, but if the item has a space in it will not continue scanning. I tried using the gets() function, however I still don't have the right result. the code:
for(int i = 0; i < n; i++){
gets(name);
scanf("%d\n",&price);
printf("%s , %d\n", name, price);
}
printf("end");
returns:
3 // Input 3 items
item a // name of first item
1 // price of item 1
item b // name of item 2
item a , 1 // the print of the first item
2 // price of item 2
item c // name of item 3
item b , 2 // print of item 2
3 // price of item 3
word // no clue where this new input came from
end // end of scanning
My question is, how would I go about correctly scanning an input such as this? I also tried changing the scan function into while((c = getchar()) != '\n');, but got the same result...
Mixing gets(), scanf() is bad as scanf() tends to leave the trailing '\n' in stdin.
Using gets() is bad.
scanf("%s", ...) is not useful for reading a line of info with spaces meant to be saved.
how would I go about correctly scanning an input such as this?
A simple alternative is to read each line into a string and then parse the string.
#include <stdio.h>
int main() {
char line[100];
int n;
fgets(line, sizeof line, stdin);
sscanf(line, "%d", &n);
for(int i = 0; i < n; i++){
char name[50];
// int price;
double price;
fgets(line, sizeof line, stdin);
sscanf(line, " %49[^\n]", name);
fgets(line, sizeof line, stdin);
// sscanf(line, "%d", &price);
sscanf(line, "%lf", &price);
printf("%s , %.2f\n", name, price);
}
printf("end");
}
Advanced: Better code would check the return values of fgets(), sscanf(). Maybe replace sscanf(line, "%lf",... with strtod().
I think you could probably figure out what's happening here pretty easily if you added some more output. Let's try shall we?
Also, first of all you're really looking for a double input - not an integer. With an integer, your scan function won't match properly based on what you're looking for. But let's add some more output!
#include <stdio.h>
int main()
{
int n;
char name[50];
double price;
printf("Enter count: ");
scanf("%d", &n);
for (int i = 0; i < n; i++) {
printf("%s\n", "Please type a name followed by a newline followed by a number and then press enter:");
scanf("%s\n%lf", name, &price);
printf("%s , %lf", name, price);
}
return 0;
}
So I think what was happening in your initial attempt was a combination of things. Mostly that you were possibly pressing enter after the output from the first iteration? That will break the scanf call - since it isn't expecting to start with a \n but it is immediately expecting you to enter a name.
Second, I don't know the number you entered in the first iteration, because you didn't supply the output of it while still using scanf - so I have nothing other than speculation. You possibly used an integer on the first go, and subsequently on the remaining iterations you chose to use decimals? Again, this is only a guess.
Sometimes it is easier to just write your own functions with error checking. Below is a suggestion. You may also want to check that the numbers are non-negative.
#include <assert.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
void ReadLine(char result[], int resultLen)
{
int ch, i;
assert(resultLen > 0);
i = 0;
ch = getchar();
while ((ch != '\n') && (ch != EOF)) {
if (i < resultLen - 1) {
result[i] = ch;
i++;
}
ch = getchar();
}
result[i] = '\0';
}
void ReadInteger(int *i)
{
int ch, count;
count = scanf("%d", i);
if (count == 1) {
do {
ch = getchar();
} while (isspace(ch) && (ch != '\n'));
} else {
fprintf(stderr, "invalid input, integer expected\n");
exit(EXIT_FAILURE);
}
}
void ReadReal(double *x)
{
int ch, count;
count = scanf("%lf", x);
if (count == 1) {
do {
ch = getchar();
} while (isspace(ch) && (ch != '\n'));
} else {
fprintf(stderr, "invalid input, real number expected\n");
exit(EXIT_FAILURE);
}
}
int main(void)
{
char name[50];
int n;
double price;
ReadInteger(&n);
for (int i = 0; i < n; i++) {
ReadLine(name, sizeof name);
ReadReal(&price);
printf("%s, %.2f\n", name, price);
}
return 0;
}
As chux said in the comments of this answer: "All scan specifiers, except %c, %[, %n consumes leading white-spaces." So you don't need to account for them.
scanf("%s%d",name,&price);
And looking at your input, you should use float or double for the price.
scanf("%s%lf",name,&price);
Note that this works only if items are made of one word. If they can be of two or more words, you'd better use fgets
EDIT: for items made of more words you should use fgets
fgets(name, 50, stdin);
scanf("%lf",&price);
Replace your for loop with this:
for (int i = 0; i < n; i++) {
scanf(" %[^\n]\n%d", name, &price);
printf("%s , %d\n", name, price);
}
The first space skips leading spaces, and the [^\n] allows you to get more than one word as string input.
Ive got this program which im stuck with in which I am trying to receive the size of a string and following it, telling the user to input the letter by letter. Here is my code.
#include<stdio.h>
#include<stdlib.h>
int main(){
int size;
int i;
char letter;
printf("Your string's size is...?: ");
scanf("%d", &size);
char mystring[size] ;
for (i=0; i<size; i++){
printf("Write a letter: \n");
scanf("%c", &letter);
mystring[i] = letter;
}
printf("%s",mystring);
system("PAUSE");
return 0;
}
Thanks!
Two problems here.
First, the %c format specifier to scanf will read any character, including a newline. You need to put a space before it to absorb any newlines in the input buffer:
scanf(" %c", &letter);
Second, you don't null-terminate the string, nor do you leave enough space in the array to store the null terminator. Make the array one element larger, and add the null byte at the end:
char mystring[size+1];
for (i=0; i<size; i++){
...
}
mystring[size] = 0;
Two things:
First, you need to terminate the string with a \0-character. Otherwise, printf will result in undefined behaviour.
Second, note that scanf("%c",..) will probably consume a new line left in the buffer when a user presses "enter" after having entered a number (i.e. the size).
Write:
char mystring[size+1] ;
for (i=0; i<size; i++){
printf("Write a letter: \n");
scanf("%c", &letter);
if (i==0 && letter == '\n') {
i--;
continue;
}
mystring[i] = letter;
}
mystring[size] = '\0';
printf("%s",mystring);
I want to store "char data type values" in an array, but it doesn't work.
First, I tried using "gets"
but it gave me a run time error.
Code was like this
int tmp = 0;
char arr[100] = { 0, };
while (arr[tmp]!=NULL)
{
gets(arr[tmp]);
tmp++;
}
for (int rtmp = 0; rtmp < a; rtmp++)
printf("%s ", arr[rtmp]);
return 0;
In a second way, I was using "scanf", but I couldn't store "char data type(it should be more than one character like string)", but only one character was available.(I tried %s, but it doesn't work)
Plus, it doesn't print the last value of array.
int a = 0;
scanf("%d", &a); //determine how much I input values
int tmp = 0;
char arr[100] ={ 0 , };
for(tmp=0;tmp<a;tmp++)
{
scanf("%c ",arr[tmp]);
fflush(stdin);
}
for (int rtmp = 0; rtmp < a; rtmp++)
printf("%c ", arr[rtmp]);
return 0;
The most "identical" for me is
without notifying "a" values("a" means how much values I input)
and storing "char values" in array..
How can I solve this problem?
Thanks in advance! Your help is always appreciated :)
Array of char data type is called Sting. You can take a string's input using scanf() and gets(). But if you use scanf(), the string will be input by pressing Space-bar or Enter. But if you use gets(), input will be given only by pressing the Enter key.
Example 1:
char s[100];
scanf("%s", s);
Example 2:
char s[100];
gets(s);
Now, if you want to input every single character individually, you can do that also:
char s[100], c;
int n, i, j;
scanf("%d", &n);
getchar();
for(i=0; i<n; i++) {
scanf("%c", &s[i]);
}
s[i] = '\0';
Now look, I wrote a getchar() after scanf("%d", &n);, because when you press enter after inputting n, a new line character ('\n') is also taken as input in the character next to n. So you must do this in case like this.
One more thing, you can take input any string containing spaces using scanf() also. Just do this:
char s[100];
scanf("%[^\n]", s);
You can not enter the individual character by following snippet of code.
char arr[10] = {0};
//unsigned char ch;
unsigned int i = 0;
printf("Enter the array elements\n");
for(i = 0; i<10; i++)
{
scanf("%c", &arr[i]);
printf("i = %d and arr[%d] = %c\n", i, i, arr[i]);
}
The result of this snippet is as per this image. enter image description here
To avoid this issue, it is recommended to enter the character without new line charactoer '\n' or without pressing enter.
Or other method is to use the array as string and input the character by gets() like this snippet.
char s[100];
gets(s);
I tried to write program that scan a string from user and check it what the user input and if it is true do somthing and if it's not do somthing else.
the code i wrote is like this:
#include<stdio.h>
#include<conio.h>
int main()
{
char string[20];
printf("Enter a sentence : ");
scanf("%s",&string);
if(strcmp(string,"what's up")==0)
printf("\nNothing special.");
else
printf("\nYou didn't enter correct sentence.");
getch();
return 0;
}
but it doesn't work correct.I think because the program can't recognize the space when it want to scan.What should i do?(I'm new to c,so please explain what did you do.)
%s format specifier can't be used to scan a string with space.
You need to use fgets()
size_t n;
fgets(string,sizeof(string),stdin);
n = strlen(string);
if(n>0 && string[n-1] == '\n')
string[n-1] = '\0';
PS: fgets() comes with a newline character.So you need to gently remove it as shown above
you can still use scanf but like this :
#include<stdio.h>
#include<conio.h>
int main()
{
char string[20];
printf("Enter a sentence : ");
scanf(" %[^\n]s",string);
if(strcmp(string,"what's up")==0)
printf("\nNothing special.");
else
printf("\nYou didn't enter correct sentence.");
getch();
return 0;
}
To prevent buffer overflow,you can write scanf(" %19[^\n]s",string);
you can use the getline1() function to get the entire line as shown below:
/* getline1: read a line into s, return length*/
int getline1(char s[],int lim)
{
int c, i;
for (i=0; i < lim-1 && (c=getchar())!=EOF && c!='\n'; ++i)
s[i] = c;
if (c == '\n') {
s[i] = c;
++i;
}
s[i] = '\0';
return i;
}
lim specifies the maximum length of the line.
Ok I am making a program that reads two characters from the user and then prints the ASCII letters between those two characters.
The problem is that when the program runs it prompts the user to enter the first character and once the user hits enter the program ends.
What am I missing?
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]){
char firstchar;
char secondchar;
int variable;
int highest;
int lowest;
char ASCIvariable;
printf("Please enter a character. ");
scanf("%d", &firstchar);
printf("Please enter another character. ");
scanf("%d", &secondchar);
if(firstchar < secondchar)
{
secondchar = highest;
firstchar = lowest;
}else{
firstchar = highest;
secondchar = lowest;
}
variable = lowest;
for ( variable != highest; variable < highest; variable++ )
{
variable = ASCIvariable;
printf(ASCIvariable);
}
return 0;
}
I clearly also don't understand how to post code on this site. I need four spaces manually entered before EVERY line of code?
Update here is the current code also control k will not allow paste....
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
char firstchar;
char secondchar;
int variable;
int highest;
int lowest;
char ASCIvariable;
printf("Please enter a character. ");
scanf(" %c", &firstchar);
printf("Please enter another character. ");
scanf(" %c", &secondchar);
if(firstchar < secondchar)
{
highest = secondchar;
lowest = firstchar;
}
else
{
highest = firstchar;
lowest = secondchar;
}
variable = lowest;
for (variable != highest; variable <= highest; variable++ )
{
ASCIvariable = variable;
printf("%c ", ASCIvariable);
}
return 0;
}
It successfully allows the user to enter both characters and then prints the letters between the two. I think that is correct?
Using wrong format specifier might lead to UB. You need to scan a character
scanf("%c", &firstchar);
Then flush the newline char using
scanf(" %c",&secondchar);
The space before the %c consumes the newline char.
1)You must get input with format specifier %c for characters
2)You must consume the newline after entering first character
3) You seem to be confused with assignment statements
a=b
assigns the valure of b to a and not the other way around.
printf("Please enter a character. ");
scanf(" %c", &firstchar);
//The space before %c will consume the newline
printf("Please enter another character. ");
scanf(" %c", &secondchar);
if(firstchar < secondchar)
{
highest=secondchar ;
lowest=firstchar ;
}
else
{
highest=firstchar;
lowest= secondchar ;
}
//Changed the for loop to get characters between two inputs
variable = lowest+1;
for ( ; variable < highest; variable++ )
{
ASCIvariable= variable ;
printf("%c ", ASCIvariable);
}
Change your code to:
printf("Please enter another character. ");
scanf(" %c", &secondchar); /* Note the extra space and %d is changed to %c*/
Also change your for loop to:
for ( ; variable <= highest; variable++ ) /* Should be <= */ {
ASCIvariable = variable; /* Reverse */
printf("%c", ASCIvariable); /* %c */
}
Your assignations are also incorrect:
if(firstchar < secondchar)
{
highest = secondchar;
lowest = firstchar;
}
else
{
highest = firstchar;
lowest = secondchar;
}
a = b; means copy contents of b into a.