2

So I've just started learning C for a class of mine, and I have been working on this assignment, but this part has me perplexed. I have some code that essentially looks like:

#include <stdio.h>
#include <string.h>

int main(void)
{
    int one = 0;
    int two = 0;
    char oneWord[100]; 
    char twoWord[100];

    printf("Enter a two digit number: ");
    scanf("%d%d", &one, &two);

    strcpy(firstWord, "Test");
    strcpy(secondWord, "Two");

    printf("%s", firstWord);

    return 0;
}

Now, logic/purpose of the program aside, what I cannot figure out is why that scanf statement is resulting in an infinite loop? I determined that was that cause of the problem when I commented it out and the final printf statement worked just fine.

I tried changing it to scanf("%d,%d", %one, %two) and that seemed to work fine when I added a comma to the input. But I want to just be able to take a number like 55 and break it into 2 digits. What exactly am I doing wrong here?

3
  • Sorry, I didn't read whole story. Change %d to %c to read only one character Commented Oct 7, 2012 at 8:31
  • Lol, literally just figured this out after posting the question. For my purposes, what worked was scanf("%1d%1d", &one, &two). Commented Oct 7, 2012 at 8:35
  • How about separating the numbers in the input with a space? Commented Oct 7, 2012 at 8:43

3 Answers 3

7

What you run into is not an infinite loop, but rather scanf waiting for more input.

The d-format-specifier means a decimal number, so anything like "0", "41", or "2342345".

After you have entered the first number, you expect the program to continue, but scanf has just completed the first %d, so scanf is waiting for you to fulfill the second %d. This is what seems to you an infinite loop, but really is scanf doing what you ordered it to.

scanf cannot guess how many digits for each number you desire. But you can tell it how you want it, with a width-specifier that tells how many characters each information is composed of:

#include <stdio.h>

int main () {
    int a, b;
    scanf("%2d%1d", &a, &b);
    printf("%d, %d", a, b);
} 

with error handling:

#include <stdio.h>

int main () {
    int a, b;
    if (scanf("%2d%1d", &a, &b) < 2)
        fprintf(stderr, "not enough digits");
    else
        printf("%d, %d", a, b);
}
Sign up to request clarification or add additional context in comments.

4 Comments

Also tell him that it is not infinite loop. instead it is waiting for just one more number to be entered.
Ah man, didn't expect so many answers this fast! But what I ended up doing was scanf("%1d%1d", &one, &two), is there any problem with doing that as opposed to your solution of scanf("%2d%1d", &one, &two)?
@This0nePr0grammer: You must understand what the digit before the d means: It is the number of digits to parse, so for "%3d" and the number "123456", scanf would give you "123". Now you should be able to answer your question yourself.
@This0nePr0grammer Welcome :) (edit: added a more detailed explanation for the "infinite loop")
2

I might be wrong, but %d means "an integer", not "a digit". So 55 is the first %d, then the second one isn't defined.

You could try with %c (one char).

3 Comments

You are probably right. See this for reference, but doesn't completely answer his question.
Also tell him that it is not infinite loop. instead it is waiting for just one more number to be entered.
To be more precise, "d" is for "decimal", meaning a "decimal number", in other words, a base 10 number.
1
printf("Enter a two digit number: ");
scanf("%1d%1d", &one, &two);

Of course even this can fail (not meet the requirements)
Instead:

scanf("%d", &one);
if (one<10 || one>99) printf("I didn't expect that...\n");

or

scanf("%s",oneWord); one = atoi(oneWord);
if (one<10 || one>99)
   printf("Thats not necessarily even a number\n");
else
   { two = one % 10; one = one / 10; 
       printf("The first digit is %d and the second is %d\n",one,two);
   }

In the latter program we are testing that the input is correct:
It's a good practice to feed garbage instead of the correct input and see, where it goes unnoticed. The library function atoi(string); returns an integer contained in a string. It's zero, if no integer was found. e.g. (atoi("a1") == 0).

But the minimum correct answer would be

scanf("%d", number);
if (number >= 10 && number <= 99) 
{
   one = number / 10;  // the first digit;
   two = number % 10;  // the second digit calculated as number modulo 10
}

scanf("%1d%d", &one, &two);  // would halt for a single character input

3 Comments

if one is a single, decimal (as in "d") digit, then how could it be bigger than 9? And an error check that is itself unsure about what it does is not a valid error check.
Try the first example and enter e.g. 123; it's not a two digit number.
I missed that you don't use a width-specifier in your second format string (unlike in the first format string). However, it wouldn't solve the questioners problem of dissecting a number string into several numbers. Also: Your second example goes a bit too far for the problem at hand. Maybe at least explain what you are doing there?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.