Answer array

Bob
Bob in C

bob.h

#ifndef BOB_H
#define BOB_H

char const *hey_bob(char const *greeting);

#endif

bob.c

#include "bob.h"
#include <string.h>
#include <stdbool.h>
#include <ctype.h>

static char const *const answers[] = { "Whatever.", "Sure.", "Whoa, chill out!",
                                 "Calm down, I know what I'm doing!" };

char const *hey_bob(char const *greeting)
{
   if (!greeting || *greeting == '\0')
      return "Fine. Be that way!";
   char const *end_pos = greeting + strlen(greeting) - 1;
   while (end_pos > greeting && isspace(*end_pos))
      end_pos--;
   if (isspace(*end_pos))
      return "Fine. Be that way!";
   char const *msg = greeting;
   bool shout = true, has_letter = false;
   while (msg <= end_pos) {
      if (isalpha(*msg)) {
         has_letter = true;
         if (!isupper(*msg)) {
            shout = false;
            break;
         }
      }
      msg++;
   }
   int is_shout = shout && has_letter ? 2 : 0;
   int is_question = *end_pos == '?' ? 1 : 0;
   return answers[is_question + is_shout];
}

In this approach you define an array that contains Bob’s answers, and each condition is given a score. The correct answer is selected from the array by using the score as the array index.

The hey_bob function starts be testing if pointer to the input string is NULL. If so, the OR (||) statement short-circuits and returns the response for saying nothing. If the pointer is not NULL, then the right side of the OR statement tests if the pointer is pointing at the terminating '\0' character. If so, then it is an empty string, and the response for saying nothing is returned.

The next thing is to calculate where the string ends, disregarding any trailing whitespace. The strlen function from string.h library is used to find the last position of the input string.

The isspace function from the ctype.h libray is used to check if the character at the end_pos is whitespace. If so, the end_pos is decremented.

If all of the characters in the input string are spaces, end_pos will be decremented until it is at the first character. If the first character is also whitespace, then the response for saying nothing is returned.

The next thing is to calculate is the input string is a shout. The msg pointer is initialized to the position of the first character. The shout variable is initialized to true as a condition to disprove, and the has_letter variable is initialized to false as a condition to prove. has_letter is needed, because if the input were only "123", shout would never be disproved, but without letters it would not really be a shout.

Each character from the first through the end_pos is checked. The isalpha function from ctype.h is used to see if has_letter should be set to true. If the characters is a letter, it's checked by the isupper function from ctype.h to see if shout should be set to false. If a character is a letter but is not uppercase, then the input string cannot be shout, so break is used to exit the loop.

After the loop, a ternary operator is used to set the value for is_shout to 2 if both shout and has_letter are true. Otherwise is_shout is set to 0.

A ternary operator is used to set the value for is_question to 1 if the character at end_pos is '?'. Otherwise, is_question is set to 0.

The value of is_shout plus is_question is used to index into the answers array for returning the correct answer. For example, giving is_question a score of 1 and is_shout a score of 0 would use an index of 1 to get the element from the answers array, which is "Sure.".

is_shout is_question Index Answer
0 0 0 + 0 = 0 "Whatever."
0 1 0 + 1 = 1 "Sure."
2 0 2 + 0 = 2 "Whoa, chill out!"
2 1 2 + 1 = 3 "Calm down, I know what I'm doing!"
11th Sep 2024 · Found it useful?