#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2012
    Posts
    9
    Rep Power
    0

    Why does printf give me this result ^*C?


    Hey, I'm just doing a tutorial and I'm wondering why its not working.
    I need the user to enter two numbers in to an array and then take one away from the other!

    #include <stdio.h>


    int main(void) {
    int numbers[2], result;
    printf("Enter two numbers:");
    scanf("%2s", &numbers[2]);
    result = numbers[0] - numbers[1];
    printf("%2s", result);

    }
  2. #2
  3. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,086
    Rep Power
    2222
    If you wanted to read in two numbers (int, I assume), why then did you read in the first two characters of the input string? And why did you store that outside of the array?

    numbers starts out containing garbage, so garbage minus other garbage is still garbage.

    in scanf, read in two values using "%d" (%s is for a string, %d is for a decimal integer). Read them in to numbers[0] and numbers[1].
  4. #3
  5. Contributed User
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    Jun 2005
    Posts
    4,363
    Rep Power
    1870
    Using a compiler that checks your printf/scanf format strings for sanity is a good idea.
    Code:
    $ gcc -Wall -Wextra bar.c
    bar.c: In function ‘main’:
    bar.c:7:1: warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘int *’ [-Wformat]
    bar.c:9:1: warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘int’ [-Wformat]
    bar.c:11:1: warning: control reaches end of non-void function [-Wreturn-type]
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper
  6. #4
  7. Contributing User
    Devshed Demi-God (4500 - 4999 posts)

    Join Date
    Aug 2011
    Posts
    4,696
    Rep Power
    480
    rtfm <-- read the manual.


    printf("%2s", result);

    "%2s" is the format string. It instructs the printf function what sort of additional arguments to expect and how to convert them onto stdout. All the output onto stdout will be "a string".

    % indicates the start of a conversion.
    2 is the field width. (that's why 2 characters display)
    s tells printf to look for a pointer to character. An address.

    dwise already told you to use d, not s for integer conversions. That is printf("%d",n); tells printf to convert the horrid incomprehensible internal binary representation of the integer n into a base 10 human readable form. rtfm.
    (Use your web search engine to search for `man printf'.)
    [code]Code tags[/code] are essential for python code and Makefiles!
  8. #5
  9. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2012
    Posts
    9
    Rep Power
    0
    Originally Posted by dwise1_aol
    If you wanted to read in two numbers (int, I assume), why then did you read in the first two characters of the input string? And why did you store that outside of the array?

    numbers starts out containing garbage, so garbage minus other garbage is still garbage.

    in scanf, read in two values using "%d" (%s is for a string, %d is for a decimal integer). Read them in to numbers[0] and numbers[1].
    Ok, why is it outside of the array?

    This gives me an answer of 68 when i enter 88

    int main(void) {
    int numbers[2], result;
    printf("Enter two numbers:");
    scanf("%d", &numbers[0], &numbers[1]);
    result = numbers[0] - numbers[1];
    printf("%d", result);

    }
  10. #6
  11. Contributed User
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    Jun 2005
    Posts
    4,363
    Rep Power
    1870
    > scanf("%d", &numbers[0], &numbers[1]);
    You're reading two numbers, so you need two %d conversions.

    scanf("%d %d", &numbers[0], &numbers[1]);

    And please start using [code][/code] tags for posting code.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper
  12. #7
  13. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2012
    Posts
    9
    Rep Power
    0
    Originally Posted by salem
    > scanf("%d", &numbers[0], &numbers[1]);
    You're reading two numbers, so you need two %d conversions.

    scanf("%d %d", &numbers[0], &numbers[1]);

    And please start using [code][/code] tags for posting code.

    Code:
    int main(void) {
    	int numbers[2], result;
    		printf("Enter two numbers:");
    		scanf("%d %d", &numbers[0], &numbers[1]);
    		result = numbers[0] - numbers[1];
    		printf("%d", result);
    		
    }
    This code just makes cmd go haywire. It doesn't give me a result or an error just stays stuck until I enter another command. Then it gives me the same 68 answer!
  14. #8
  15. Contributed User
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    Jun 2005
    Posts
    4,363
    Rep Power
    1870
    *shrug*
    Works just fine for me.
    Code:
    $ cat bar.c
    #include <stdio.h>
    
    int main(void) {
        int numbers[2], result;
            printf("Enter two numbers:");
            scanf("%d %d", &numbers[0], &numbers[1]);
            result = numbers[0] - numbers[1];
            printf("%d", result);
            
    }
    $ gcc -Wall -Wextra bar.c
    bar.c: In function ‘main’:
    bar.c:10:1: warning: control reaches end of non-void function [-Wreturn-type]
    $ ./a.out 
    Enter two numbers:123 45
    78$ 
    $ ./a.out 
    Enter two numbers:123
    23
    100$ 
    $
    You did actually type in two numbers separated by a space, and not just "68", expecting to see the result of 6 - 8
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper
  16. #9
  17. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2012
    Posts
    9
    Rep Power
    0
    Originally Posted by salem
    *shrug*
    Works just fine for me.
    Code:
    $ cat bar.c
    #include <stdio.h>
    
    int main(void) {
        int numbers[2], result;
            printf("Enter two numbers:");
            scanf("%d %d", &numbers[0], &numbers[1]);
            result = numbers[0] - numbers[1];
            printf("%d", result);
            
    }
    $ gcc -Wall -Wextra bar.c
    bar.c: In function ‘main’:
    bar.c:10:1: warning: control reaches end of non-void function [-Wreturn-type]
    $ ./a.out 
    Enter two numbers:123 45
    78$ 
    $ ./a.out 
    Enter two numbers:123
    23
    100$ 
    $
    You did actually type in two numbers separated by a space, and not just "68", expecting to see the result of 6 - 8

    Facepal*

    Thank you very much, I understand it a lot better now!
  18. #10
  19. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,086
    Rep Power
    2222
    Replying since it was addressed to me and just in case you haven't figured it out yet on your own.

    Originally Posted by the5thace
    Originally Posted by dwise1_aol
    And why did you store that outside of the array?
    Ok, why is it outside of the array?
    This is the code in question, which was in your original posting (highlighted in red):
    Code:
    int numbers[2], result;
    printf("Enter two numbers:");
    scanf("%2s", &numbers[2]);
    You declared the array, numbers, to contain two elements. The indices of those two elements are 0 and 1. There is no valid index of 2, since that would be outside the array. In fact, the non-existent numbers[2] "element" would occupy the int-sized memory locations right after the array, memory locations that have been allocated for other uses, such as other local variables or function-call management, including the return address from the function. When you overwrite memory that either does not belong to you or was allocated to other uses (this happens most commonly when you use an uninitialized pointer or address outside of the range of an array -- buffer-overflow attacks are directly based on the latter), then that is called clobbering, which can cause you all kinds of "inexplicable" problems, including causing your program to crash (if you're lucky).

    You may have been coddled by other modern languages that go out of their way to protect you from yourself, but C doesn't coddle anyone. C was created by experienced programmers who knew what they were doing in order to be used by experienced programmers who knew what they were doing. As a result, C naturally assumes that you know what you are doing and will let you do just about anything, no matter how stupid, since you know what you are doing. That is why C doesn't waste any time or resources to perform range-checking, because that's the responsibility of the programmer, who's supposed to know what he's doing. Oh, it will warn during compile-time when you do something stupid, but it will still let you go ahead and do it anyway. This is the reason why you must always turn on warnings and never ignore those warnings. Warnings are far more important than error messages.

    Does that answer your question?
  20. #11
  21. Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Aug 2009
    Posts
    149
    Rep Power
    36

    Comments on this post

    • b49P23TIvg agrees : Some authors showed more patience than I had.

IMN logo majestic logo threadwatch logo seochat tools logo