C for loop suddenly stops [duplicate] - arrays

This question already has answers here:
scanf() leaves the newline character in the buffer
(7 answers)
Closed 9 months ago.
I'm trying to read distance between two nodes in a Graph and store it in an array but the loop doesn't work as expected. It suddenly stops.
Output:
Edge Number: 4
Enter distance between two nodes, Example: A B 10
A C 3
A B 2
C B 2
...Program finished with exit code 0
Press ENTER to exit console.
For example, when edgeNumber is 4, it stops at 3. Here's my code. Thanks in advance.
Code:
#include <stdio.h>
#define S 50
int main(){
int dist[S][S], edgeNumber, i, temp;
char node1, node2;
printf("Edge Number: ");
scanf("%d", &edgeNumber);
printf("Enter distance between two nodes, Example: A B 10 \n");
for(i = 0; i < edgeNumber; i++){
scanf("%c %c %d", &node1, &node2, &temp);
dist[((int)node1) - 65][((int)node2) - 65] = temp;
dist[((int)node2) - 65][((int)node1) - 65] = temp;
}
return 0;
}

Just rewrite this call of scanf
scanf("%c %c %d", &node1, &node2, &temp);
^^^
like
scanf( " %c %c %d", &node1, &node2, &temp);
^^^
The leading space in the format string allows to skip white space characters in the input buffer including the new line character '\n'.
Also it is a bad idea to use magic numbers like 65. And you should check entered characters that they are letters and convert them to upper case. Otherwise your code is very unsafe. Also you should test the result of calls of scanf.

Related

C printf printing trash before the right values [duplicate]

This question already has answers here:
scanf() leaves the newline character in the buffer
(7 answers)
Closed 9 months ago.
I'm trying to read distance between two nodes in a Graph and store it in an array but the loop doesn't work as expected. It suddenly stops.
Output:
Edge Number: 4
Enter distance between two nodes, Example: A B 10
A C 3
A B 2
C B 2
...Program finished with exit code 0
Press ENTER to exit console.
For example, when edgeNumber is 4, it stops at 3. Here's my code. Thanks in advance.
Code:
#include <stdio.h>
#define S 50
int main(){
int dist[S][S], edgeNumber, i, temp;
char node1, node2;
printf("Edge Number: ");
scanf("%d", &edgeNumber);
printf("Enter distance between two nodes, Example: A B 10 \n");
for(i = 0; i < edgeNumber; i++){
scanf("%c %c %d", &node1, &node2, &temp);
dist[((int)node1) - 65][((int)node2) - 65] = temp;
dist[((int)node2) - 65][((int)node1) - 65] = temp;
}
return 0;
}
Just rewrite this call of scanf
scanf("%c %c %d", &node1, &node2, &temp);
^^^
like
scanf( " %c %c %d", &node1, &node2, &temp);
^^^
The leading space in the format string allows to skip white space characters in the input buffer including the new line character '\n'.
Also it is a bad idea to use magic numbers like 65. And you should check entered characters that they are letters and convert them to upper case. Otherwise your code is very unsafe. Also you should test the result of calls of scanf.

Scanf is adressing wrong type of variable to arrays [duplicate]

This question already has answers here:
scanf() leaves the newline character in the buffer
(7 answers)
Closed 3 years ago.
For example, 1st input is "B 2 A 0" press Enter. team1[0] = 'B' and rest of it is addressing True. No problem so far.
But in 2nd input this happens.. assume that this is my 2nd input >> "A 1 B 1"
team1[1] is not 'A'. as you guessed score1[1] and score2[1] is not 1 either, and that's why im asking.
// the first versions of the arrays
// 0x7fffffffea60 "p\353\377\377\377\177" team1[size]
// 0x7fffffffea50 "\240\353\377\377\377\177" team2[size]
// after 1st input ( assume "B 2 A 0" )
// 0x7fffffffea60 "B\353\377\377\377\177" team1[size]
// 0x7fffffffea50 "A\353\377\377\377\177" team2[size]
// after 2nd input ( assume "A 1 B 1" )
// 0x7fffffffea60 "B\n\377\377\377\177" team1[size]
// 0x7fffffffea50 "A\353\377\377\377\177" team2[size]
char team1[size];
char team2[size];
int score1[size];
int score2[size];
for(i=0;i<size;i=i+1)
{
scanf("%c %d %c %d",&team[i],&score1[i],&team2[i],&score2[i]);
}
With
char team1[size];
char team2[size];
int score1[size];
int score2[size];
for(i=0;i<size;i=i+1)
{
scanf("%c %d %c %d",&team[i],&score1[i],&team2[i],&score2[i]);
}
And as you say
1st input is "B 2 A 0" press Enter.
the enter is not read by your first scanf and is still available, so the second loop the first %c gets it then scanf see A for the first %d and returns without setting score1[1] team2[1] and score2[1]
As said in a remark you can use " %c %d %c %d", that bypasses spaces and newlines at the beginning of the input.
Note you already uses that bypassing putting a space between %d and %c so N 2 A 0 is read as expected
As also said in a remark check the result of scanf valuing 4 when the inputs are ok
#include <stdio.h>
#define size 100
int main()
{
char team1[size];
char team2[size];
int score1[size];
int score2[size];
int i, j;
for(i=0; i < size; ++i)
{
if (scanf(" %c %d %c %d", &team1[i], &score1[i], &team2[i], &score2[i]) != 4)
break;
}
/* check */
puts("input values:");
for(j=0; j<i ; ++j)
{
printf("%c %d %c %d\n", team1[j], score1[j], team2[j], score2[j]);
}
}
Compilation and execution :
pi#raspberrypi:/tmp $ ./a.out
B 2 A 0
A 1 B 1
C 22 D13
input values:
B 2 A 0
A 1 B 1
C 22 D 13
(I used the non visible control+d to finish the input)

Trying to make scanf not go to a new line in a for loop (C Programming)

Sorry if my English is poor. What I'm trying to do is get the scanf to be entered on the same line. For example Enter value: 1 6 8 9 4 1 2 8 5 and it to be separated by a space. Then the numbers to be stored in an array. This is my code:
#include <stdio.h>
int main(void)
{
int a[10], smallest, i;
printf("Random\n");
for (i = 0; i < 9; i++)
scanf("%d", &a[i]);
smallest = a[0];
for (i = 0; i < 9; i++)
{
if (a[i] < smallest)
{
smallest = a[i];
}
}
printf("\nSmallest Element : %d\n", smallest);
}
Thanks for any help!
Edit: I'm trying to make the user enter 9 numbers which are stored in the array using scanf but when entering the numbers the scanf goes to a new line for example:
> 5
> 6 and so on what I want is for them to enter the number numbers on the same line with a space in between like this Enter value: 1 6 8 9 4 1 2 8 5
Scanf will await for a complete line. I suggest you take your input as a string then use strtok to extract the values and then assign.
Edit: You could use the scanf like that:
scanf( "%d %d ...", &a[0], &a[1]...); //as many values you're to assign
However, I prefer the method I proposed initially. Keep in mind scanf is derived from "scan formatted". You'll also have to handle the result from the scanf, it returns the number of values successfully filled.
you can scanf all numbers in one statement: scanf("%d %d %d %d %d %d %d %d %d %d", &a[0], &a[1], &a[2], &a[3], &a[4], &a[5], &a[6], &a[7], &a[8], &a[9]);
This will let you scan 10 numbers with spaces between them, without the need to hit enter every time
note that I scanned 10 ints, because your array can store 10 ints, while your loop only scans 9... (to fix it, change i < 9 to i < 10 as Sourav Ghosh suggested)

Scanning line of input with char and num

So I'm doing this problem where I need to calculate the average using pointers and without using strings. The user will input a letter and then a space followed by a number(an integer), the letter indicating if the number is positive(p) or negative(n) or if the user is done input-ing numbers(e).
I know I need a loop to continually read in number and add or subtract them from the sum until the letter "e" is input.
program should have and use the following function
// Precondition: value will be a pointer to where the input value is to be stored.
// Postcondition: returns true if a number was read, or false if
// it was the end of the list. The int pointed to by value will be
// set to the number input by this function, made negative or
// positive depending on the character before it. int read_number(int* value)Íž
A sample input being p 20 p 20 p 10 p 10 e
output: 15
My problem as of now is my loop is only reading for two cycles of input, and even then it isn't printing the average. Also I'm supposed to use a pointer but given the directions i'm still not sure what the context is, I'm not seeing where a pointer is useful.
#include <stdio.h>
//precondition: value will be a pointer to where the input value is to be stored.
int main(){
int sum;
int num;
int counter;
float avg;
char let;
scanf("%c %d", &let, &num);
for (counter=0;let == 'n' || let == 'p'; counter++){
scanf("%c %d", &let, &num);
if ( let == 'n'){
sum-=num;
}
if (let == 'p'){
sum+=num;
}
if ( let == 'e'){
avg=sum/counter;
printf("%f", &avg);
}
}
return 0;
}
Your input is:p 20 p 20 p 10 p
10 e.
The scanf before the loop scans 'p' and then skips the space and then scans 20. The next scanf in the loop reads the space as it is also a character and the %d fails to scan an int and the stops scanning. See the problem?
To fix it, change
scanf("%c %d", &let, &num);
To
scanf(" %c %d", &let, &num);//Note the space before %c
The space before %c gobbles up whitespace characters(if any) like newlines, spaces etc until the first non whitespace character.
Other problems include not initializing sum to 0 and using &avg instead of avg in the printf below
printf("%f", &avg);

C for loop iteration

I have a problem writing code which does the following: declare a struct{char c; int x; } array and load it with scanf via a loop. After it's loaded, a call to function f will be made which will replace every occurrence of digits in the struct's component c with 0, and will return the sum of the digits replaced by zero.
Code and output are below and I have problem that the loop in the function f seems to iterate one time, and it gives out some really weird values.
This is an exam question so I have to use printf, scanf etc. Also I have that exam in an hour so any quick help is appreciated :)
CODE:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#define MAX 2
struct par {
char c;
int x;
};
int f(struct par *niz) {
int i;
int n=0;
for(i=0; i<MAX; i++) {
if(isdigit(niz[i].c)) {
niz[i].c = niz[i].c-'0';
printf("niz[i].c = %d\n i = %d", niz[i].c, i);
n=n+niz[i].c;
niz[i].c='0';
}
}
return n;
}
void main() {
int n;
int i;
struct par niz[MAX];
printf("enter\n");
for(i=0; i<MAX; i++) {
scanf("%c", &niz[i].c);
scanf("%d", &niz[i].x);
}
n=f(niz);
for(int i=0; i<MAX; i++) {
printf("%d\n", niz[i].c);
printf("%d\n", niz[i].x);
}
printf("n = %d\n", n);
}
OUTPUT:
enter
2
2
2
niz[i].c = 2
i = 048
2
10
2
n = 2
When you press enter after the first input, the newline is not scanned by scanf and is left in the input buffer. When you then try to read the number scanf sees the newline and not a number so doesn't scan anything.
The simple solution to that is to add a leading space in front of the formats:
scanf(" %c", &niz[i].c);
scanf(" %d", &niz[i].x);
/* ^ */
This tells scanf to skip whitespace.
Use
niz[i].c = getchar();
instead of
scanf("%c", &niz[i].c);
or, you can use other better methods for getting char input discussed at SO,
Now,
You see second time you provided input only once, that is because the Enter you pressed after giving 2 as input to first char remained in input buffer, and was read on second iteration.
You are getting 10 as output, because, it is ASCII for \r, the Enter. It is not a digit, so not replaced to be '0'.
I am looking at your code (i am not using console for a decade, but ) here are some insights:
try to rename MAX with something else
do not know your IDE but sometimes MAX is reserved
and using it as macro can cause problems on some compilers
change scanf("%c", &niz[i].c) to scanf("%c", &(niz[i].c))
just to be shore that correct adsress is send to scanf
change scanf("%d", &niz[i].x) to scanf("%i", &(niz[i].x))
change "%d" to the correct value (this is main your problem)
"%c" for char
"%i" for int
Try to trace line by line and watch for improper variables change if above points does not help
weird values?
because you forgot "\n" after the line, so next print is behind the line "i = %d".
And, check return value of every function except ones that return void.

Resources