-2

I want to write an if-else statement that checks if a char inputted is the length of 1.

char temp;

printf("Enter colour: ");
scanf(" %c", &temp);

if (strlen(temp) > 1) {
    printf("Value most only be one character");
}

else {
    nextFunction();
}

However, using strlen() here makes my program halt and I don't know why. I also tried changing the third line to scanf(" %s", &temp) but this didn't work either. How else can I check and handle the length of the char input?

Jabberwocky
  • 48,281
  • 17
  • 65
  • 115
ao2000
  • 1
  • 1
  • 3
    I think you're confused about the difference between a `char` and an array of `char`s. Also, read https://stackoverflow.com/questions/57842756/why-should-i-always-enable-compiler-warnings . – Sneftel Nov 08 '22 at 09:38
  • 3
    `char` will always contain exactly 1 character. You need to use an array to read multiple characters. – VLL Nov 08 '22 at 09:38
  • 1
    `temp` being a `char` will always hold a single character. Maybe you want to read the input as a string (an array of `char`s), and then validate its length. – wohlstad Nov 08 '22 at 09:38
  • 2
    A char has always a length of 1. `sizeof ( char )` gives 1. If you want to check multibyte inputs, you at least need `%s` instead of `%c`. – mouviciel Nov 08 '22 at 09:39
  • I'd read the chapter dealing with strings in your C text book. – Jabberwocky Nov 08 '22 at 09:40
  • 1
    Turn on compiler warnings. This issue should have been detected by compiler. – hyde Nov 08 '22 at 09:46

1 Answers1

1

You're reading and storing a single character by definition.

A variable of type char stores a single character value - 'A', '\n', '5', etc.

Your scanf call only reads a single character - the format string " %c" tells scanf to skip over any whitespace and read the next non-whitespace character, which gets stored to temp.

The strlen call is blowing up because it expects the argument to be a pointer to the the first character of a 0-terminated string - basically, an address, and no single character value is going to be a valid pointer value.

In this case the strlen call is unnecessary - all you really need to do is check the return value of scanf to make sure the input operation succeeded. scanf will return the number of input items successfully read and assigned or EOF on end of file or error:

if ( scanf( " %c", &temp ) == 1 )
  // do something with temp
else
  // EOF or error

If you want to store a string, then you need to create an array of char:

#define MAX_STRING_LENGTH 20 // or however long your string can be
...
char str[MAX_STRING_LENGTH+1]; // +1 for the string terminator

if ( scanf( "%s", str ) == 1 ) // note no & operator
  // do something with str

This is not safe - if you enter a string that's longer than the array can hold, those excess characters will be written to the memory following the array, potentially overwriting something important.

You can make that safer by specifying a maximum width in the format specifier:

scanf( "%20s", str );

but it has to be hardcoded - you can't use a runtime parameter like you can with printf. You can create a preprocessor macro that will expand to "%20s" (or whatever you set MAX_STRING_LENGTH to):

#define EXP(x) #x
#define FMT(x) "%" EXP(x) "s"

if ( scanf( FMT(MAX_STRING_LENGTH), str ) == 1 )
  // do something with str

but it's just safer and easier to use fgets instead:

if ( fgets( str, sizeof str, stdin ) )
  // do something with str

The only hitch here is that fgets will store the trailing newline to the array if there's room, so you'll have to handle that somehow:

size_t end = strlen( str );  
if ( str[end] == '\n' )      
  str[end] = 0;              
John Bode
  • 119,563
  • 19
  • 122
  • 198