-3

I'm trying to do a simple code but I'm having hard time while trying to make it work.

I want to get an int from stdin between 1 and 50.

if the number is 1 then to print A

if the number is 11 then to print J

if the number is 12 then to print Q

if the number is 13 then to print K

Edit: If its none of them, then just return the number.

i tried to use %c but it wont work for numbers from 10 and above

then i managed to do it by using switch but the default part is not working for me. the only thing i managed to do is to make 50 case's for each number but that's just look horrible.

any help would be appreciated.

#include <stdio.h>

main() {
    int number;
    scanf("%d", &number);
    char*  card = NULL;
    switch (number)
    {
    case 1:
        card = "A";
        break;
    case 11:
        card = "J";
        break;
    case 12:
        card = "Q";
        break;
    case 13:
        card = "K";
        break;
    default:
        card = //Dont know what to write here//;
    }
    printf("%s\n", card);
    return 0;
}
t.elazari
  • 300
  • 2
  • 11
  • 1
    so basically take a number from 1-50 and convert into the equivalent card face value for a game of poker (or whatever?) – Marc B Jul 22 '16 at 21:39
  • First mistake in your code, ignoring the return valud of `scanf()`. And you better make `char *` `const char *` if it's going to point to a string literal, and also check for `NULL` before `pritnf()` if you're going to use `NULL` as an invalid value. – Iharob Al Asimi Jul 22 '16 at 21:50
  • You didn't say what you would like to do with the card when its value is something other than 1, 11, 12, or 13. – R Sahu Jul 22 '16 at 21:51
  • 1
    For `0 -9` you could use `'0' + number` to turn the number into the character equivalent. For larger numbers I'd use `sprintf`. – Retired Ninja Jul 22 '16 at 21:52
  • Sorry if im not clear, if its not 1,11,12 or 13,- then just return the number – t.elazari Jul 22 '16 at 21:53
  • 1
    @iharob Disagree, an earlier mistake is using `scanf()` instead of `fgets()`. – chux - Reinstate Monica Jul 22 '16 at 22:25
  • @user3121023 True about "numbers 1-50". Consider `face = ( ( -10 - 1) % 13) + 1;` `x%13` will puts numbers in to the range -12 ... 12. – chux - Reinstate Monica Jul 22 '16 at 22:31

4 Answers4

2

As far as I can see, this code should work:

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

#define MAX_STRING_SIZE (sizeof(int)*CHAR_BIT/3 + 3)

int main(int argc, char **argv) {
    int number = 0;
    scanf("%d", &number);
    char card[MAX_STRING_SIZE] = {0};
    switch (number)
    {
    case 1:
        strcpy(card, "A");
        break;
    case 11:
        strcpy(card, "J");
        break;
    case 12:
        strcpy(card, "Q");
        break;
    case 13:
        strcpy(card, "K");
        break;
    default:
      sprintf(card, "%d", number);
    }
    printf("%s\n", card);
    return 0;
}

Note that you cannot assign strings with: card = "whatever", you must use strcpy() found in the string.h library. For the default part of your code, I assumed you were trying to convert the card input which was not 1, 11, 12, or 13. In which case, you can use sprintf() to convert the integer value to a string.

I hope this helps!

Community
  • 1
  • 1
iRove
  • 562
  • 1
  • 9
  • 19
  • I'd put a `if (number > 1 && number <= 50)` before the `sprintf`. Otherwise, a number like `123456` will overflow your buffer. – user3386109 Jul 22 '16 at 22:02
  • 1
    @user3386109 :) Hopefully though, users won't be entering numbers like `123456`. – iRove Jul 22 '16 at 22:11
  • 2
    Users are evil -- first rule of software development :) – user3386109 Jul 22 '16 at 22:21
  • `#define MAX_STRING_SIZE (sizeof(int)*CHAR_BIT/3 + 3)` Other tighter formulas exist. (Avoid "len" when "size" is needed too) – chux - Reinstate Monica Jul 22 '16 at 22:26
  • @chux Interesting...I have never heard of being able to decide a `MAX_STRING_SIZE` like this. Any idea where I can learn more about how this formula works? Thank you for pointing me in the right direction! – iRove Jul 23 '16 at 00:07
  • 1
    @iRove `sizeof(int)*CHAR_BIT` is at least the number of value bits in `INT_MIN`, so it is about `log2(-INT_MIN)`. That times `log10(2)` (a bit less than 1/3) is at least `log10(-INT_MIN)`. `sizeof(int)*CHAR_BIT/3 + 1` is then at least the number of digits in `INT_MIN`. Add 1 for the `-`, add 1 for `\0` leads to `(sizeof(int)*CHAR_BIT/3 + 3)`. – chux - Reinstate Monica Jul 23 '16 at 01:21
  • @chux Thanks for the explantation: it really helped, so I get it for the most part. However, there is one thing I want to clarify. I was [looking here](http://stackoverflow.com/a/25848970/4520911) to understand exactly why you divide by 3. It seems to me that this is because the space required for an integer in bits is always generally proportional to the maximum number of digits that the computer could possibly read in (assuming we are reading in a typical `int` with `%d`). Is my assumption correct? – iRove Jul 23 '16 at 03:51
  • 1
    @iRove Say you had a `B` binary number. How many decimal digits `D` would the equivalent be? `D = B * log10(2) = B * 0.301..`. or about `B/3` – chux - Reinstate Monica Jul 23 '16 at 04:27
  • @chux Sorry it took me so long to respond. I understand now ([this link](http://www.exploringbinary.com/number-of-decimal-digits-in-a-binary-integer/) ended up helping me as well). Thank you for taking your time to write that simplified explanation and helping me understand it further! I will update my answer with the formula you suggested. – iRove Jul 26 '16 at 00:17
1
#define MINCARD   1
#define MAXCARD  50
const char *num2card(int n)
{
    static char buf[3];
    assert(n >= MINCARD && n <= MAXCARD && "Inval card no.");

    switch (num) {
    case 1:
        return "A";
    case 11:
        return "J";
    case 12:
        return "Q";
    case 13:
        return "K";
    default:
        snprintf(buf, 3, "%d", num);
    }
    return buf;
}
lost_in_the_source
  • 10,998
  • 9
  • 46
  • 75
  • 1
    Same problem iRove originally had - buffer too small for larger values. 11 digits should be enough for 32-bit ints, though I'd use 16 then (power of two). – Aconcagua Jul 22 '16 at 22:20
  • 1
    @Aconcagua Note: `"-2147483648"` needs at least `char buf[12];` – chux - Reinstate Monica Jul 23 '16 at 02:11
  • @chux Oh, yes, your right. So many years of experience - and still not safe from forgetting the trailing 0. What a shame... Perhaps should stop coding/writing comments at 1 am... – Aconcagua Jul 23 '16 at 06:09
0

Use an array of char. Each numerical "case" will correspond to an index in the array, and the element at that index will be the appropriate "card".

As for what the "default" value should be - that is a requirements question. What is the purpose of this application?

Robert Columbia
  • 6,313
  • 15
  • 32
  • 40
0

you can try sprintf, but you still have to add in logic for what happens if the number is larger than 50.

#include <stdio.h>
#include <stdlib.h>
int main() {
    int number;
    scanf("%d", &number);
    char*  card = malloc(8);
    switch (number)
    {
    case 1:
        card = "A";
        break;
    case 11:
        card = "J";
        break;
    case 12:
        card = "Q";
        break;
    case 13:
        card = "K";
        break;
    default:
        sprintf (card , "%i" , number );
    }
    printf("%s\n", card);
    return 0;
}
brianxautumn
  • 1,162
  • 8
  • 21
  • 1
    The `sprintf` will crash because `card` doesn't point to a valid memory area. – user3386109 Jul 22 '16 at 21:59
  • It's [undefined behavior](https://stackoverflow.com/questions/2397984/undefined-unspecified-and-implementation-defined-behavior) to use a pointer that hasn't been properly initialized. One of the consequences of undefined behavior is that your program may appear to work even though it's horribly broken. This you will learn soon enough. – user3386109 Jul 22 '16 at 22:06
  • My bad, I forgot to give it some memory, you were right. – brianxautumn Jul 22 '16 at 22:14
  • 1
    Why 8 in `malloc(8)` - a guess? Maybe not worried about `-2000000` or if `int` is wider than 32- bit? – chux - Reinstate Monica Jul 22 '16 at 22:20
  • Yeah. you would have to decide the max string size beforehand. – brianxautumn Jul 22 '16 at 22:23
  • Pack this in a function in a more complex program, and there already is a wonderful memory leak, as the array is not freed any more. Sure, not dramatic in *this* example, but if coding this style gets a habit... – Aconcagua Jul 23 '16 at 06:11
  • Wait, actually, I don't think you need malloc. Its just going to create a memory leak because sprintf will change where it points to anyway. – brianxautumn Jul 23 '16 at 06:36