My little program below shall take 5 numbers from the user, store them into an array of integers and use a function to print them out. Sincerly it doesn't work and nothing is printed out. I can't find a mistake, so i would be glad about any advice. Thanks.
#include <stdio.h>
void printarray(int intarray[], int n)
{
int i;
for(i = 0; i < n; i ++)
{
printf("%d", intarray[i]);
}
}
int main ()
{
const int n = 5;
int temp = 0;
int i;
int intarray [n];
char check;
printf("Please type in your numbers!\n");
for(i = 0; i < n; i ++)
{
printf("");
scanf("%d", &temp);
intarray[i] = temp;
}
printf("Do you want to print them out? (yes/no): ");
scanf("%c", &check);
if (check == 'y')
printarray(intarray, n);
getchar();
getchar();
getchar();
getchar();
return 0;
}
Change your output in printarray() to read:
printf("%d\n", intarray[i]);
^^
That will add a newline after each number.
Normally, output written to the console in C is buffered until a complete line is output. Your printarray() function does not write any newlines, so the output is buffered until you do print one. However, you wait for input from the user before printing a newline.
Change to that:
char check[2];
And also that:
scanf("%s", check);
if (!strcmp(check,"y"))
printarray(intarray, n);
Hope that helped. Your scanf("%c", &check); failed. Instead of y you end up having NL (ASCII code 10), which means the if part fails.
I don't know if it a nice fix though. Maybe someone could give a better one. Keep in mind if you input something bigger (eg yess) you going to get a bit unlucky ;)
Aside from the suggestions about printing the \n character after your array (which are correct), you also have to be careful with your scanf that expects the "yes/no" answer. Muggen was the first one to notice this (see his answer).
You used a %c specified in your scanf. %c specifier in scanf does not skip whitespace, which means that this scanf will read whatever whitespace was left in the input buffer after you entered your array. You hit the "Enter" key after entering the array, which put a newline character into the input buffer. After that scanf("%c", &check) will immediately read that pending newline character instead of waiting for you to enter "yes" or "no". That's another reason your code does not print anything.
In order to fix your scanf, you have to force it to skip all whitespace characters before reading the actual answer. You can do that by scanf(" %c", &check). Note the extra space before %c. Space character in scanf format string forces it to skip all continuous whitespace beginning from the current reading position. Newline character happens to be whitespace, so it will be ignored by this scanf.
printf("%d", intarray[i]);
add new line after this
Related
while(letter!='e'){
scanf(" %c %i %i",&letter,&xPos,&yPos);
grid[xPos][yPos] = 1;
}
I want the loop to end when letter ='e';. I need to input e twice to end the loop. I know that my scanf expects the 2 integers as well, and that this somehow mankes me to need to input e twice. How do i fix this?
You can refer to the sample program below to rectify your doubt. For the most part, you don't have to worry about the \n, because scanf() is programmed in such a way that it would skip any interleaving white space (which includes \n). Although, knowledgeable people say that it's better if you assume that scanf() reads the format exactly as it is typed. The problem is that %c behaves differently. Reading from the manual about %c, it says:
The usual skip of leading white space is suppressed.
To skip white space first, use an explicit space in the format.
So really to fix this call and the program, you just add that explicit space:
scanf(" %c", &o);
#include <stdio.h>
int main() {
char letter;
int xPos,yPos;
int grid[3][3]={{0}};
while(letter !='e'){
printf("enter letter\n");
scanf(" %c",&letter);
if(letter=='e')
break; // here break is used to immediately end the program after entering 'e' as per your requirement
printf("enter xpos and ypos\n");
scanf(" %i %i",&xPos,&yPos);
grid[xPos][yPos] = 1;
}
for(int i=0;i<3;i++){
for(int j=0;j<3;j++){
printf("%d",grid[i][j]);
}printf("\n");
}
}
In my c class today I was troubling with the scanf() command, we were just learning pointers and we got a question asking us to get an array, and print it reversed without using the [] for anything but declaring the (int) array. Of course it seems like a piece of cake but not when you accidentally write:
scanf("%d ", arr + i);
Did you notice the space after the %d? Sure did take me a while to figure it out but for some reason that makes loops go crazy, and I wanted you guys to help me (and my teachers) to figure out why does that happen. Example:
#include <stdio.h>
#define LEN 10
void arrayInput(int * arr, unsigned int len);
void arrayReverseOutput(int * arr, unsigned int len);
int main(void)
{
int arr[LEN] = { 0 };
arrayInput(arr, LEN);
arrayReverseOutput(arr, LEN);
system("pause");
return 0;
}
void arrayInput(int * arr, unsigned int len)
{
unsigned int i = 0;
printf("Enter 10 numbers: ");
for (i = 0; i < len; i++)
{
//printf("i = %d \n", i); see what happens when you use this line
scanf("%d ", arr + i);
}
}
void arrayReverseOutput(int * arr, unsigned int len)
{
int i = 0;
printf("The numbers in reverse order: ");
for (i = --len; i >= 0; i--)
{
printf("%d ", *(arr + i));
}
}
I'm really curios to see what's going on with that scanf... it's as if it requires 2 inputs at the first time it runs but somehow still manages to put the inputs in their right position in the array...
Thanks for taking your time to read this <3
A space in the format string tells scanf() to match zero or more whitespace characters, until the match fails. Spaces (' '), newlines('\n'), carriage returns ('\r'), and tabs ('\t') are among the whitespace characters. When a space occurs at the end of a format string, scanf() will try to match whitespace characters from the input until no match is found. But, scanf() can only return when a match fails, or end of file is reached. Thus, in the case of a statement like:
scanf("%d ", arr + i);
the call to scanf() will appear to hang, greedily waiting for more input from the user. Whenever the Enter key is pressed, a newline is sent and matched by scanf(), which is still waiting for a failing match. Or end of file. You can escape such a loop by signalling end of file from the keyboard with Ctrl-D on Linux, or Ctrl-C on Windows.
It is almost always a mistake to terminate a scanf() format string with a space. A newline ('\n') is also a whitespace character, and has the same effect when placed at the end of a format string.
Note that spaces can be used effectively in scanf() format strings. For example:
int retval = scanf(" %c %c", &c1, &c2);
Here, if a previous IO operation has left a newline in the input stream (a not uncommon occurrence), the leading whitespace directs scanf() to read and ignore it. The second space in the format string tells scanf() to expect zero or more whitespace characters between the input characters to be converted. This allows the user to input the characters with an intervening space. Without the added whitespace, if a user entered a b\n, c2 would end up holding the value for a space character, and the b would be left behind in the input stream for the next IO operation to pick up. Also note that scanf() returns the number of successful conversions, allowing the program to check whether the input is as expected. If retval in the above line is anything other than 2, something has gone wrong.
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!
I write a C program to pick the data from the the std input, which starts with a number indicating the number of the data sets, then there are N pairs of data, in the form: (x y), so I write the code as below:
#include <stdio.h>
int main()
{
int n_sets;
scanf("%d", &n_sets);
int i;
for(i = 0; i < n_sets; ++i)
{
int m, n;
scanf("(%d %d)", &m, &n);
printf("%d\t%d\n", m, n);
}
return 0;
}
but it doesn't work. After I input the number of the data set, the program print the uninitialized m&n directly. But when I add a space before the (%d %d), it works fine. Somebody can explain this?
When you have character literals in your argument to scanf(), it expects to find those literals exactly as specified in the format string.
scanf("%d", &n_sets);
correctly reads n_sets, and stops at the newline or other whitespace character in the buffer. The next scanf() :
scanf("(%d %d)", &m, &n);
expects to find an open parenthesis at the beginning of the input, but finds a whitespace character instead. So it fails, and scanf() returns without having read anything. Consequently, your m and n remain uninitialized, and garbage results.
When you put in the space before the open parenthesis like so:
scanf(" (%d %d)", &m, &n);
it tells scanf() to skip any leading whitespace before the parenthesis in the input buffer, so the program works correctly.
change
scanf("%d", &n_sets);
to
scanf("%d\n", &n_sets);
and input your n_sets ending up with a [enter], it works.
Assuming your input is like this:
2 (1 2) (3 4)
There is a space(or new line?) after the first number, so change the scanf in the loop to:
scanf("\n(%d %d)", &m, &n);
// ^^
It sounds like the input into the program has some amount of whitespace before the value you want scanf to parse. The space in the string tells scanf to ignore whitespace. Without it, scanf is looking for an exact match immediately.
I am trying to take five character and 5 float input.
main()
{
char c[5];
float q[5];
int i;
for(i=0;i<5;i++)
{
printf("\n%d ",i);
scanf("%c",c+i);
scanf("%f",q+i);
}
}
But the output is absurd. After two sequential scans, it skips third scan and then again skips fifth scan.
I am not able to understand why is it showing such a behaviour.
I am working on gcc compiler.
Use of scanf is not recommended because of problems like this.
Instead use fgets to read the entire line and then use sscanf to extract what you want(a char or a float) from the line just read:
char line[MAX];
for(i=0;i<5;i++)
{
if( fgets(line,MAX,stdin) && sscanf(line,"%c", c+i)!=1 )
*(c+i) = 0;
if( fgets(line,MAX,stdin) && sscanf(line,"%f", q+i)!=1 )
*(q+i) = 0.0;
printf("%c %f\n",*(c+i),*(q+i));
}
To directly answer why the 3rd and every other scan "skips", it is the way scanf() and the %c format works. When there is a call to scanf(), you typically have to press enter to "submit" the input. Consequently that inserts a newline character into the stdin stream.
When the previous float scan got inputted, the newline is still left in the stream. When the character scan gets reached, that remaining newline character is read in since it fits effectively "skipping" the call.
You should use fgets() with sscanf() as codaddict suggests.
But as a quick fix, you could try adding a call to getchar() after the float scan to consume that newline character from the stream.
edit:
You're saying this doesn't work? (assuming you input the correct kinds of values, one per scanf call)
main()
{
char c[5];
float q[5];
int i;
for(i=0;i<5;i++)
{
printf("\n%d ",i);
scanf("%c",c+i);
scanf("%f",q+i);
getchar();
}
}
You should try this:
int main(){
char c[6];//char array size must be 6 to store five charecter
//as null-terminator('\0')will use the last one
float q[5];
int i;
for(i=0;i<5;i++){
printf("\n%d\n",i);fflush(stdout);
scanf("%c",&c[i]);fflush(stdin);//fflush(stdin) to clear input stream that
//next scanf() won't skip
scanf("%f",&q[i]);fflush(stdin);//fflush(stdin) to clear input stream that
//scanf() won't skip at new loop
}
return 0;
}
fflush() is not defined on an input stream, like stdin. Don't do it.
If you want to "read and discard until newline", then do:
int ch;
do {
ch = getchar();
} while (ch != EOF && ch != '\n');
Note that %c means "read the next character in the input stream, even if it's whitespace, then stop". %f means "read and discard whitespace, then try to read a float from the input stream, then stop."
Your code should be like this :
main()
{
char c[5];
float q[5];
int i;
for(i=0;i<5;i++)
{
printf("\n%d ",i);
scanf("%c",c+i);
while (getchar()!='\n');
scanf("%f",q+i);
while (getchar()!='\n');
}
}
the sentence while (getchar()!='\n'); search till the end of input, so it would not take '\n' as an input value for q+i.Also another while (getchar()!='\n'); after scanf q+i,since you use loop.
Problem in scanning a char value after a float value.
Solution is very simple!!!
instead of writting your code like this
scanf("%c",&...)
try this,
scanf(" %c",&...)
A Space before the"%c" will resolve the problem by neglecting the value of the Return(Enter) key when pressed after typing the value of the float as an input.
When a float value is scanned before a character value.
The value obtained by pressing the Return(Enter) key is collected in the following char variable. Using a space before(" %c",&...) discards the value collected of the Return(Enter) Key, Causing the Char value to be scanned in the next line. Thus solving The Scanning Float-Char problem.