How to Convert a String to the NATO Phonetic Alphabet in C

The challenge

You’ll have to translate a string to Pilot’s alphabet (NATO phonetic alphabet).

Input:

If, you can read?

Output:

India Foxtrot , Yankee Oscar Uniform Charlie Alfa November Romeo Echo Alfa Delta ?

Note:

  • There are preloaded dictionary you can use, named NATO
  • The set of used punctuation is ,.!?.
  • Punctuation should be kept in your return string, but spaces should not.
  • Xray should not have a dash within.
  • Every word and punctuation mark should be seperated by a space ‘ ‘.
  • There should be no trailing whitespace

The solution in C

Option 1:

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

// NATO['A'] == "Alfa", etc
extern const char *const NATO[128];

char *to_nato(const char *words)
{
  char* s = calloc(1000, 1);
  char* r = s;
  while(*words){
    if(isalpha(*words))     sprintf(s, "%s%s ", s, NATO[toupper(*words)]);
    else if(*words != ' ')  sprintf(s, "%s%c ", s, *words);
    words++;
  } 
  s[strlen(s) - 1] = '\0';
  return r;
}

Option 2:

#include <string.h>

extern const char *const NATO[];
char *to_nato (const char *s) { char *r,*t=*(s+=strspn (s," "))&&s[1]?to_nato (s+1):""; asprintf (&r,*t?"%s %s":"%s", *s?strchr (",.!?",*s)?(char[2]){*s,0}:NATO[*s&~32]:"", t); return r; }

Option 3:

#include <stdlib.h>
#include <string.h>
#include <ctype.h>

// NATO['A'] == "Alfa", etc
extern const char *const NATO[];

char *to_nato(const char *words){
  char *nato = (char *)calloc(strlen(words) * 20, 1);
  while(*words != '\0'){
    if(isalpha(*words)){
      strcat(nato, NATO[toupper(*words)]);
      strcat(nato, " ");
    }else if(strchr(",.!?", *words) != NULL){
      strncat(nato, words, 1);
      strcat(nato, " ");
    }
    
    words++;
  }
  
  char *p = strchr(nato, '\0');
  *(p - 1) = *p;
  return nato; // Go code
}

Test cases to validate our solution

#include <criterion/criterion.h>

extern void do_test(const char *words, const char *expected);

Test(sample_test, example_tests)
{
    do_test("If you can read",
            "India Foxtrot Yankee Oscar Uniform Charlie Alfa November Romeo Echo Alfa Delta");
    do_test("Did not see that coming",
            "Delta India Delta November Oscar Tango Sierra Echo Echo Tango Hotel Alfa Tango Charlie Oscar Mike India November Golf");
    do_test("go for it!",
            "Golf Oscar Foxtrot Oscar Romeo India Tango !");
}