7

Is it possible to scanf a defined data type?

#include <stdio.h>
enum numberByMonth {jan=1,feb,mar,apr,may,jun,jul,aug,sep,oct,nov,dec};
main(){
printf("\n");
printf("Get Number By Month (type first 3 letters): ");
enum numberByMonth stringy;
scanf("%u",stringy);
printf("Your month number is: %u",stringy);
}

Can someone help me with which datatype I should scan for? I set it to %u because gcc told me it was an unsigned integer.

4
  • 2
    Why main() with no type? Commented Nov 24, 2013 at 18:08
  • 2
    Your format specifier is fine. You need to pass the address of stringy into scanf. i.e. scanf("%u",&stringy) Commented Nov 24, 2013 at 18:09
  • AAAAAH thank you simonc, I just forgot the ampersand. Thanks. Commented Nov 24, 2013 at 18:11
  • @simonc You should probably post this as an answer. Commented Nov 24, 2013 at 18:27

2 Answers 2

5

The code you wrote should be working, but not in the way you intended, in fact, enum are treated as integer after compilation and remains no trace in the object file of your "jan,feb,mar,apr,may,jun,jul,aug,sep,oct,nov,dec", for this reason your program just parses an unsigned number from command line with scanf and returns the same number after printf.. You probably wanted this

#include <stdio.h>
#include <string.h>
char* months[] = {"jan","feb","mar","apr","may","jun","jul","aug","sep","oct","nov","dec"};

int main()
{
    printf("\n");
    printf("Get Number By Month (type first 3 letters): ");
    char str[3];
    scanf("%s",str);
    int i;
    for(i=0; i<12; i++)
    {
        if(!strcmp(str,months[i]))
        {
            printf("Your month number is: %d",i+1);
        }
    }
    return 0;
}

which doesn't use enums, but it is reasonable because enums are used to preserve source readability without impairing efficiency and for this reason are threated as integers not strings, so if what you want to do is string parsing, you have to use strings because you have to compare user input with "jan", "feb" etc..

Sign up to request clarification or add additional context in comments.

2 Comments

Well, actually I made that program to test enums, but you were right, it didn't work the way intended.
So, why not award him the answer?
0

No, it is not possible to use scanf to read an enum type -- at least, not portably.

The problem is that you do not know how big the enum is. So you don't know whether to use %d or %hd or %hhd (or, perhaps, %u or %hu or %hhu) to read the values.

If you write

scanf("%u", &stringy);

as in the question (and with the missing & added), then scanf is going to read a number and write it onto the stringy variable, but it is going to assume that stringy is an unsigned int, occupying sizeof(unsigned int) bytes of memory.

But if the compiler has decided that it can actually use a short int or maybe even just a char to hold enum numberByMonth, this is going to overwrite memory, resulting in undefined behavior.

The OP said that "gcc told me it was an unsigned integer", and that may have been true on that day, but it won't necessarily be true on another day, or under a different compiler.

The safe way to fix this, although it's cumbersome, is to use a temporary variable which you can be sure of the size of:

unsigned int tmp;
scanf("%u", &tmp);
stringy = tmp;

It would also be possible to make the assumption that enums are always going to be int-sized (that is, to assume that the compiler is never going to make them smaller), but to protect that assumption with an assertion:

assert(sizeof(stringy) == sizeof(unsigned int));
scanf("%u", &stringy);

See also What is the size of an enum in C?

1 Comment

The last suggestion is technically undefined behaviour as %u is only for unsigned int, and not other types that may happen to be the same size as unsigned int.

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.