I am trying to write a simple program that uses scanf to input 5 numbers from the user and add them together. Here is the code I have so far..
int main()
{
int i;
int j=1;
int k=1;
for (i=1; i<= 5; i++)
{
scanf("%d\n", &j);
k = k+j;
}
printf("%d\n", k);
}
But here's what happens when I run the program:
1
2
3
4
5
5
16
Basically, it asks me for a sixth number (obviously, I just need 5), and it also adds one to the final result. (1+2+3+4+5=15).
Any thoughts on this. Am I making a simple mistake somewhere?
As others have said, you are initializing k incorrectly, but I suspect that what's causing your problem is that you are using scanf("%d\n", &j); instead of scanf("%d", &j);. scanf() ignores whitespace leading up to the match.
Initially k = 1. Then you add the numbers 1, 2, 3, 4, 5 to it. Altogether they sum up to 1+1+2+3+4+5, which is 16.
You should generally think about initializing variables.
i doesn't need to be initialized before the for loop.
j doesn't need to be initialized, since it will be read from the input.
k needs to be properly initialized. But since it has a certain purpose you should rather call it sum than k. And when you sum up things, you should start with 0.
Additionally you should check whether the call to scanf was successful. In that case the function returns 1.
if (scanf("%d", &j) == 1) {
sum += j;
} else {
fprintf(stderr, "Invalid input.\n");
break; /* exit the for loop. */
}
You seem to be initializing k (which is the number you hold your sum in) as one, then adding all the other numbers to it. Try this:
int k = 0;
instead.
Then, when you do
k = k+j
the first time, k will be 0, and not 1. You also don't need to do j=1.
That said, you can also use a shortcut for k = k +j;
k += j;
C programmers have to do this pattern so much that they built a shortcut into the language specifically for it.
In your for loop, it's convention in C to start at zero and work to < your max number, as well:
for (i = 0; i < 5; i++)
I'm not sure why it's asking an extra time, but try setting your loop as that and seeing if it works.
This is what you want, k initialized at 0 and doing a scanf input without the \n which is an endline :
int main() {
int i;
int j=0;
int k=0;
for (i=1; i<= 5; i++){
scanf("%d", &j);
k = k+j;
}
printf("%d\n", k);
}
The '\n' character is unnecessary. I suspect you are mixing up your printf and scanf syntax :P
Related
I am trying to find the closest pair of numbers entered by the user. My C code isn't working right and I can't figure out what's wrong. I think it might have something to do with storing the values but I don't know where to go from here.
#include <stdio.h>
#include <math.h>
int main()
{
int i, j,arr[50], first,second;
//loop input
for(i=0;i<50;i++) //loop 50 times
{
scanf("%d", &i); //scan
//break if i=-1
if (i==-1)
break;
//if not print
}
//2nd num - 1st num < 3rd num-1st num, closest = 1st and 2nd num
//i[0]=num1, j[0+i]=2nd num, i= 4 , 5, 7, ans=arr,
//if j[0+i]-i[0]= ans < j[0+i]-i[i]=ans
//arr[i]=8,2,17,4,25
for(i=0;i<50;i++)
{
for(j=i+1;j<50;j++)
{
if(arr[j]-arr[i]<arr[j+1]-arr[i])
{
first = arr[i];//3
second = arr[j+1];//5
}
}
}
printf("%d %d\n", first, second);
return 0;
}
Don't post it as answer, prefer editing your code instead. Anyway, the problem is here :
for (j = i + 1; j < len; j++)//j<i <-why is it wrong?
How isn't it wrong? You've initialised j with the value i+1. How's it supposed to be ever less than i? And due to that, it's picking up values from outside the array and providing you with unexpected results.
The correct form is :
for (j = 0; j < i; j++)
The problem is with this chunk of code. You're scanning in the counter variable i instead of array. And then you're manipulating stuff using array arr. Why should that work in any scenario?
for(i=0;i<50;i++) //loop 50 times
{
scanf("%d", &i); //scan
//break if i=-1
if (i==-1)
break;
//if not print
}
And i can never be -1 unless it's a miracle.
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 5 years ago.
Improve this question
I have the following problem reading two strings through scanf: I insert the first string and everything it's OK, but after I insert the second one the first one changes.
#include<stdio.h>
#define N 6
#define K 2
int main(){
char a[N];
char b[K];
int i = 0,j=0;
printf("first word\n\n\n");
scanf("%s", a);
for(i = 0; i <= N; i++){
printf("%c", a[i]);
}
printf("second word \n\n\n");
scanf("%s", b);
for(i = 0; i <= N; i++){
printf("%c", a[i]);
}
}
The first time it prints it correctly. The second time it prints a similar string (maybe the first scanf is still getting the input when I'm inserting the second one)
To begin, you are printing the array a twice; it seems that you mean to print b with the second loop. But there is a problem in your loops. They are going out of array bounds. Since arrays are zero-indexed in C, you need:
for (i = 0; i < N; i++) {}
for a, and:
for (i = 0;i < K; i++) {}
for b.
But even this is not quite right, since the input strings may not entirely fill the arrays. You really need to terminate the loop when the null-terminator is reached, or when the end of the array has been reached:
for (i = 0; a[i] != '\0' && i < N; i++) {}
and:
for (i = 0; b[i] != '\0' && i < K; i++) {}
Of course, it would be simpler to just use puts() to print the strings.
It seems that the inputs (abcabc and abc) were too large for the arrays, causing buffer overflow. This can be avoided by specifying maximum widths when using the %s conversion specifier with scanf().
Here is a modified version of the posted code. I increased the sizes of N and K by one, since it appears that space for null-terminators was not considered in the original code:
#include <stdio.h>
#define N 7
#define K 3
int main(void)
{
char a[N];
char b[K];
int i = 0;
printf("first word\n\n\n");
scanf("%6s", a);
for (i = 0; a[i] != '\0' && i < N; i++) {
printf("%c", a[i]);
}
putchar('\n');
printf("second word \n\n\n");
scanf("%2s", b);
for (i = 0; b[i] != '\0' && i < K; i++) {
printf("%c", b[i]);
}
putchar('\n');
return 0;
}
You are printing a twice, change the second printf("%c", a[i]); to printf("%c", b[i]); .
The problem you are experiencing is because you invoke undefined behavior by failing to insure the strings are nul-terminated and by using incorrect limits regarding b. For instance, you
#define N 6
#define K 2
...
char a[N], b[K];
a can hold a total of 5-chars + the nul-terminator, for a total of 6-chars. b on the other hand, can only hold 1-char + the nul-terminator for a total of 2-chars.
When you then subsequently loop of both a and b with for(i = 0; i <= N; i++), not only have you guaranteed to access an element outside the bounds of the array, e.g. a[6] (valid indexes are 0-5), you have also invoked undefined behavior for any a with less that 6 total characters by attempting to read from an uninitialized value (those uninitialized array elements after the last valid char in word of say, 3-chars) When you invoke Undefined Behavior, the execution of your code is unreliable from that moment forward.
In your case you can eliminate undefined behavior by using field width modifiers to limit the number of characters placed in the arrays by scanf itself, e.g.
if (scanf ("%5s", a) != 1) {
fprintf (stderr, "error: invalid input - a.\n");
return 1;
}
You validate the return of scanf to insure the proper number of conversions have taken place, or you handle the error if they have not.
You prevent reading beyond the bounds of the array by limiting your read and output char loop to only valid characters within the array. You do that by checking the character to be printed is not the nul-terminating character, and when the nul-terminating character is reached, you exit the loop without attempting to print it.
Putting those pieces together, you could do something similar to the following (note j is unused in your code so it is commented out):
#include <stdio.h>
#define N 6
#define K 2
int main (void ) {
char a[N], b[K];
int i = 0/*, j = 0*/;
printf ("enter first word: ");
if (scanf ("%5s", a) != 1) {
fprintf (stderr, "error: invalid input - a.\n");
return 1;
}
for (i = 0; a[i] && i < N; i++)
printf ("%c", a[i]);
putchar ('\n');
printf ("enter second word: ");
if (scanf ("%1s", b) != 1) {
fprintf (stderr, "error: invalid input - b.\n");
return 1;
}
for (i = 0; b[i] && i < N; i++)
printf ("%c", b[i]);
putchar ('\n');
return 0;
}
Example Use/Output
$ ./bin/twowords
enter first word: cats
cats
enter second word: dogs
d
I would strongly caution you to consider reading line-oriented input with a line-oriented input function like fgets. This eliminates many pitfalls for new programmers. The only additional step when using fgets is to recall it reads up-to-and-including the trailing '\n', so you need to trim the '\n' from the string read.
Look things over an let me know if you have further questions.
For the second printf you have to write
printf("%c", b[i]);
As per inputs(abcabc and abc ) you mentioned your are providing to scanf are causing overflow for both the variables a and b,
You should enter string of length 5 for first and 1 for second keeping space for \0 for both the strings
Edit: Also change loop condition from i <= N to i<N or i<sizeof(a).
Please note the loop will print garbage characters past string length if the length of string happens to be less than 5
I see two things that you can do here:
Use another big buffer array that you will load data to, and that copy data to specyfic array. Than you will get max 6 letters of first word in a[], and max 2 letters of second word in b[]. But you will be able to load 2 words.
Scanf specyfic amount of chars like #xing mentiond in comment.
scanf("%6s",word) //general use, not in OP's case
Than when you've got longer word than size that you set up, you will have the rest of input as input in second word.
This question already has answers here:
how to scanf unknown amount of integer numbers into array in C?
(3 answers)
Closed 6 years ago.
I am doing a assignment which requires the input of a list of numbers and get the output when I press Enter on the keyboard. This is the code I am trying the use to get the list of numbers when I enter, but it doesn't work:
#include <stdio.h>
int main(){
int arra[100];
int i ;
int j = -1;
while (scanf("%d",&i) != 1){
arra[++j] = i;
}
printf("\n");
int k;
for(k = 0; k < j; k++){
printf("%d",arra[k]);
}
return 0;
}
I want to print the elements of arra.
First off, massive kudos for testing the return value from scanf, most people just blindly assume it works. It's just a shame you're using it in the wrong way :-)
You want the loop to continue as long as the return value is 1, meaning that you managed to scan an integer. That means it should be:
while (scanf ("%d", &i) == 1) {
That also means that any non-numeric input will cause scan failure and hence the while loop will exit. So, if you enter:
3 1 4 1 5 9 stop
you should successfully see the numeric values from the array.
The only other thing is to clean up your j handling since the k loop will stop early. This can be done with:
for (k = 0; k <= j; k++) {
Alternatively, leave that loop alone and just change how you initialise and modify j:
int j = 0;
:
arra[j++] = i;
I tend to find the second choice more C-like since j is then a count of the elements in the array rather than the maximum index.
And, of course, you're open to a buffer overflow attack at the moment since you assume nobody will enter more than a hundred numbers. So, don't use this as a homework solution (what you have is good enough with the slight bug fixes) but I'd tend to write it as something like:
#include<stdio.h>
#define SZ 100
int main (void){
int arra[SZ], i, nxt = 0;
while ((nxt < SZ) && (scanf ("%d", &(arra[nxt])) == 1))
nxt++;
printf ("\n");
for (i = 0; i < nxt; i++)
printf ("%d ", arra[i]);
return 0;
}
Check the below code:
#include<stdio.h>
int main(){
int arra [100];
int i ;
int k;
int j = 0; /* index from 0 */
printf("Keep entering numbers and press q once done \n");
while (scanf("%d",&i) == 1){ /* scan for integers */
arra[j++] = i;
}
printf("\n");
for(k = 0; k < j; k++){
printf("%d",arra[k]);
}
return 0;
}
My task is read two strings of digits and save them in different arrays.
I decided to use scanf function, but program can read only first string.
This is my bad-code.
int main()
{
int firstArray[50], secondArray[50], i, j;
/* fill an array with 0 */
for(i=0; i<50; ++i)
{
firstArray[i]=secondArray[i]=0;
}
i=j=0;
while((scanf("%d", &firstArray[i]))== 1) { ++i; }
while((scanf("%d", &secondArray[j]))== 1) { ++j; }
/* Print this. */
for(i = 0; i < 20; ++i)
{
printf("%d ", firstArray[i]);
}
putchar('\n');
for(j = 0; j < 20; ++j)
{
printf("%d ", secondArray[j]);
}
return 0;
}
I just don't understand how scanf function works. Can someone please explain?
scanf ignores blank characters (including new line). Thus your scan will read entire input into firstArray if you have no "non blank" separator.
If file/data has ; at end of first line it will stop the read into firstArray there, and never read anything into secondArray - as you never consume the ;.
/* This will never be 1 as ; is blocking */
while((scanf("%d", &secondArray[i])) == 1) {
So: if you separate with i.e. ; you will have to read / check for this before you read into secondArray.
You could also add something like:
char c;
/* this can be done more tidy, but only as concept */
while((scanf("%d", &firstArray[i])) == 1 && i < max) {
++i;
if ((c = getchar()) == '\n' || c == ';')
break;
}
Also instead of initializing array to 0 by loop you can say:
int firstArray[50] = {0}; /* This set every item to 0 */
Also take notice to ensure you do not go over your 50 limit.
You say strings of digits and you read %d. The format scans the input for the longest sequence representing an integer (signed) value. Two "digit strings" are consumed by the first while loop.
EDIT Instead of "strings of digits" you should say "strings of integers". In this case it is a little bit more subtle since the first while can consume all the integers, unless they are separated by something that is not a possible integer (e.g. a ;).
So, to make the following to work, you must separate the two "lines" with something that can't be parsed as integer and which is not considered "white character". Not the better solution, but one the possible.
#include <stdio.h>
#include <ctype.h>
int main()
{
int firstArray[50] = {0};
int secondArray[50] = {0};
int i, j, l1, l2;
int tmp;
i = j = 0;
// read integers, but not more than size of array
while( scanf("%d", &firstArray[i]) == 1 && i < sizeof(firstArray) ) {
++i;
}
// consume non digits
for(tmp = getchar(); tmp != EOF && !isdigit(tmp); tmp = getchar());
// on EOF you should exit and stop processing;
// we read one more char, push it back if it was a digit
if (isdigit(tmp)) ungetc(tmp, stdin);
while( scanf("%d", &secondArray[j]) == 1 && j < sizeof(secondArray) ) {
++j;
}
l1 = i; // preserve how many ints were read
l2 = j;
/* Print this. */
for(i = 0; i < l1; ++i)
{
printf("%d ", firstArray[i]);
}
putchar('\n');
for(j=0; j < l2; ++j)
{
printf("%d ", secondArray[j]);
}
return 0;
}
EDIT A solution that maybe fits your need better is to read the lines (one per time) into a buffer and sscanf the buffer.
You cannot use scanf to do that.
Read the documentation.
Observations:
with scanf if you enter a digit your loop runs forever
there is no check on size 50 limit of your arrays
if you press return then it ignores that line because does not match your pattern
if you enter a letter the pattern does not match and loop breaks
So use some other function, maybe gets, atoi or strtol. And remember to check the size 50 limit of your arrays.
Actually, there is one special point in C's arrays.
Though you declare an array's size. say int arr[5]; You can store values beyond the size of 5. It doesn't show any error but leads to undefined behavior (Might overwrite other variables).
Please Refer this question: Array size less than the no. of elements stored in it
In you case, that was your problem. The compiler had never passed beyond the first while statements. Thus, you didn't get any output. In fact, it didn't even compile the whole code yet!
while((scanf("%d", &firstArray[i]))== 1) { ++i; }
So, you could write this while statement like this:
while( scanf("%d", &firstArray[i]) ==1 && i<50 )
i++;
or else:
while(i<50 )
{
scanf("%d", &firstArray[i]);
i++;
}
or else:
for (i=0; i<50; i++)
scanf("%d", &firstArray[i]);
I am a math student, and I'm learning the very basics in programming in C. I need a program to read an input consisting in an array, the components of which must have certain requisites; I would like the program to ask the user for the components of the array. The user should then have to enter such components separating them with spaces. The details aren't important to get the main question across; I'll choose a simpler example then the one I am dealing with: let's say I want an array with 6 components not to contain the number 4. So I tried:
#include <stdio.h>
int main(void) {
int a[6];
printf("enter components: ");
int i;
for (i = 0; i < 6; i++) {
scanf("%d", &a[i]);
if (a[i] == 4) printf(" \n\n4 is not allowed, try again\n\n");
}
for (i = 0; i < 6; i++) {
printf("%d ", a[i]);
}
}
If I compile this and run it, and for example enter:
1 2 3 4 5 6
I will get my error message, but only after having pressed enter, that is after having entered all six components (not straight after having pressed space for the fourth time). So here are my questions (I am looking for solutions which don't make use of strings or pointers, unless it is impossible to do without them):
Is there a way to get the program to read a component (and to act accordingly) straight after its subsequent space has been entered? I'm guessing there isn't because scanf only works after the user presses enter, and not space, correct?
If there isn't, is there a way to get the program to read the components all at once after having pressed enter at the end, but letting the user pick up from the last right component? For example, with the above input, I would like the program to display something like this:
4 is not allowed
1 2 3 _
so that the user can correct his/her input (possibly changing the first three digits as well).
Sorry if this question is too dumb! Thank you for your help!!
EDIT: Well, thanks for the great answers, you have all been very helpful! It's a pity I can't accept more than one.
In for loop, after each iteration, the counter add by one automatically. If you get an invalid input, you should prevent the counter increasing. To do this, just add i--; to your code when you give an invalid input.
#include <stdio.h>
int main(void) {
int a[6];
printf("enter components: ");
int i;
for (i = 0; i < 6; i++) {
scanf("%d", &a[i]);
if (a[i] == 4){
printf(" \n\n4 is not allowed, try again\n\n");
i--;
}
}
for (i = 0; i < 6; i++) {
printf("%d ", a[i]);
}
}
Please see the bellow code:
#include <stdio.h>
int main(void) {
int a[6];
int i;
bool hasError = false;
int errorIndex = 0;
do{
hasError = false;
printf("enter components: ");
for (i = 0; i < errorIndex; i++)
printf("%d ", a[i]);
for (i = errorIndex; i < 6; i++) {
scanf("%d", &a[i]);
if (a[i] == 4 && hasError == false){
printf(" \n\n4 is not allowed, try again\n\n");
hasError = true;
errorIndex = i;
}
}
}while(hasError == true);
for (i = 0; i < 6; i++) {
printf("%d ", a[i]);
}
}
This is related to your terminal being in "cooked" mode. Characters aren't even sent to the program until the user presses enter.
You could do something like this:
int i,a[6];
for (int i=0;i<6;i++) {
scan: scanf("%d",&a[i]);
}
for (int i=0;i<6;i++) if (a[i]==4) {
printf("4 is not allowed. re-enter the last %d numbers\n",6-i);
goto scan;
}
note that in most case, it's better to avoid using goto, but in this case I think that it's natural.
If you really want, you can print the first i numbers (before the goto), but it's complicated (and platform-depended) to let the user change those numbers.
Improving on Mir Milad Hosseiny answer (I wrongly identified it as being an out of control infinite loop... it's actually exactly the infinite loop I describe in my comment)...
I would write a small function that has either a "white list" (things you want) or a "black list" things you don't want, and check each value to either belong or not (depending on the approach) to the list. That way you can keep a separate place where your store the values that you are willing to accept or the values you are not, so your primary function doesn't get really messy with exceptions or inclusions in the "if"
so your code would be
if(isAllowed(a[i]){
myList[j] = a[i]; //j is your alternate counter
}