Unit test with check testing framework
As OP did not explicitly state the review goals, here are some general ideas.


Use const when referenced data is not changed. Allows for optimizations and defined behavior when the array address passed is const.

// int IBQplain(int pos, char *str, int offset);
// int IBQdouble(int pos, char *str, int offset);
// int IBQsingle(int pos, char *str, int offset);
int IBQplain(int pos, const char *str, int offset);
int IBQdouble(int pos, const char *str, int offset);
int IBQsingle(int pos, const char *str, int offset);

Use size_t as the type for array indexes.  int maybe insufficient.

// int IBQplain(int pos, char *str, int offset);
int IBQplain(size_t pos, char *str, size_t offset);

As the functions only return 1 of 2 values, consider _Bool or bool

#include &lt;stdbool.h&gt;
// int IBQplain(size_t pos, char *str, size_t offset);
bool IBQplain(size_t pos, char *str, size_t offset);

As these functions appear to be stand-alone, suggest more pessimistic range checking:

// if (pos == offset)
if (pos &lt;= offset)
  return 0;  /* Not within quotes */

... otherwise if the below 3 are only helper functions to isBetweenQuotes(), they should be static.

static int IBQplain(int pos, const char *str, int offset);
static int IBQdouble(int pos, const char *str, int offset);
static int IBQsingle(int pos, const char *str, int offset);

Unclear why code accesses the array again instead of ch

for (ch = str[offset]; ch; ch = str[++offset]) {
    if (!escaped) {
      // switch (str[offset]) {
      switch (ch) {

Expect more test cases that have incomplete '' and "" pair combinations, especially onces that begin or end the string.