1

I am very new to coding, and am taking an online course with very little help. I am working through an assignment creating a bunch of functions that will be used at a later date. I have not learned anything about points, arrays, or recursions at this point. My knowledge of strings is pretty much limited to the "printf" function.

With that being said, I have been given this description for how the function "ranking_to_string" should operate:

This function should convert the hand_ranking_t enumerated value passed in to a string that describes it.

The enumerated type here is hand_ranking_t, which ranks a poker hand in descending order of value from STRAIGHT_FLUSH (0) to NOTHING (8). With that all being said, this is the function I have created to attempt to follow my instructions:

const char * ranking_to_string(hand_ranking_t r) {
  switch (r) {
  case STRAIGHT_FLUSH: printf("STRAIGHT_FLUSH\n"); break;
  case FOUR_OF_A_KIND: printf("FOUR_OF_A_KIND\n"); break;
  case FULL_HOUSE: printf("FULL_HOUSE\n"); break;
  case FLUSH: printf("FLUSH\n"); break;
  case STRAIGHT: printf("STRAIGHT\n"); break;
  case THREE_OF_A_KIND: printf("THREE_OF_A_KIND\n"); break;
  case TWO_PAIR: printf("TWO_PAIR\n"); break;
  case PAIR: printf("PAIR\n"); break;
  case NOTHING: printf("NOTHING\n"); break;
  default: printf("Invalid thing\n"); break;
  }
  return EXIT_SUCCESS;
}

I am wondering, am I correct in returning EXIT_SUCCESS (0) at the end of the function? Is there another way to convert the enum value entered into a string using printf?

Quinn
  • 33
  • 3
  • `EXIT_SUCCESS` is some numeric constant. Your function returns `char *` though... – alex01011 Jul 04 '21 at 22:50
  • There's no purpose in returning anything from this function, you should make it of `void` type. If you really need to return the `EXIT_SUCCESS` you should make it of type `int`. – czarson Jul 04 '21 at 22:54

2 Answers2

3

EXIT_SUCCESS is a macro that will expand into an environment defined indicator to be returned from main (or via exit, etc.) to indicate that your entire program has successfully done what it is supposed to do. It's generally not used outside this context.

printf is used to send output to the stream associated with stdout. For example, you might call printf to display text in your terminal.

Your function should instead return the string literals, to be used by the caller of ranking_to_string.

const char *ranking_to_string(hand_ranking_t r) {
    switch (r) {
        case STRAIGHT_FLUSH: return "STRAIGHT_FLUSH";
        case FOUR_OF_A_KIND: return "FOUR_OF_A_KIND";
        /* ... and so on ... */
        default: return "Invalid thing";
    }
}

An example program:

#include <stdio.h>

typedef enum {
    STRAIGHT_FLUSH,
    FOUR_OF_A_KIND,
    /* ... and so on ... */
} hand_ranking_t;

const char *ranking_to_string(hand_ranking_t r) {
    switch (r) {
        case STRAIGHT_FLUSH: return "STRAIGHT_FLUSH";
        case FOUR_OF_A_KIND: return "FOUR_OF_A_KIND";
        /* ... and so on ... */
        default: return "Invalid thing";
    }
}

int main(void) {
    hand_ranking_t rank = FOUR_OF_A_KIND;
    const char *rank_string = ranking_to_string(rank);

    printf("My ranking is <%s>\n", rank_string);
}

Output:

My ranking is <FOUR_OF_A_KIND>
Oka
  • 23,367
  • 6
  • 42
  • 53
  • I see, this makes a lot of sense! It seems I did not understand what constitutes a string in C. To clarify for my own sake, adding quotation marks to a _string_ of characters is what makes a string, and when I use the function printf, all I am doing is outputting a string to the user? – Quinn Jul 04 '21 at 23:01
  • @Quinn I've updated the answer with a whole bunch of links to the appropriate documentation. But yes and yes. For example, `"Hello world"` is a *string literal*, which is really a pointer to a block of read-only memory where this data is contained. That's why the return type of your function is `const char *`. `printf` is just a function which takes a `const char *` as its first argument, and uses this to send data to a stream (this may be the terminal output, or perhaps a different file). – Oka Jul 04 '21 at 23:12
  • @Quinn If your learning resource hasn't explained this well enough, then I would suggest finding another. These are rather fundamental concepts, that usually should be taught in an increasing order of complexity (i.e., core syntax and basic types should be explained before function calls, usually). Consider scanning the [The Definitive C Book Guide and List](https://stackoverflow.com/questions/562303/the-definitive-c-book-guide-and-list) for a better learning resource. – Oka Jul 04 '21 at 23:17
0

Probably not covered in your course, but it's possible to automate ranking_to_string entirely by using X-Macros. Also, since poker hands have value, it makes sense to list them by it.

#include <stdlib.h>
#include <stdio.h>

#define HANDS X(HIGH_CARD), X(PAIR), X(TWO_PAIR), X(THREE_OF_A_KIND), \
    X(STRAIGHT), X(FLUSH), X(FULL_HOUSE), X(FOUR_OF_A_KIND), \
    X(STRAIGHT_FLUSH), X(ROYAL_FLUSH)

#define X(name) name
enum hand { HANDS };
#undef X
#define X(name) #name
static const char *hand_str[] = { HANDS };
#undef X
static const size_t hand_size = sizeof hand_str / sizeof *hand_str;

int main(void) {
    enum hand i, j;
    for(i = 0; i < hand_size; i++) printf("%s\n", hand_str[i]);
    i = FULL_HOUSE;
    j = FLUSH;
    printf("%s is %s than %s.\n",
        hand_str[i], i < j ? "less" : "greater", hand_str[j]);
    return EXIT_SUCCESS;
}

Where # is the stringizing operator of the pre-processor.

Neil
  • 1,767
  • 2
  • 16
  • 22
  • 2
    Generally, you'll want the commas to be part of the X macro, not the macro list. In case you wish to use the macro list for other things than enums or initializer lists. – Lundin Jul 05 '21 at 09:57
  • Good point. In `C99`, optional trailing commas were added to the initializer list syntax, and it is more versatile that way. – Neil Jul 05 '21 at 10:23