Swap first and last name in C I took an entire line of input in the form of a string, and tokenized the string into substrings and obtained the first string as the first name and the second as the last name. This program as it stands is very basic and limited however my primary focus was on the creation of generic functions to do all the heavy lifting (generic as in they are not specific to the program and could be used elsewhere I've had several problems in the past where my functions are to narrowed on a specific problem, so please tell me how I did!).

The function for parsing the string, get_substr(), most likely can, and should, be improved and I am hoping for better ideas on how to do it!

/*Input name: first, last. Output name: Last, first*/
#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;string.h&gt;
#include &lt;stdbool.h&gt;

#define MAXSIZE 1024

bool readline(char *line, const size_t buffer_len);
bool hasDigits(const char *str);
bool hasPunct(const char *str);
void chop_newline(char *str);
char *remove_leading_whitespace(char *str);
char *get_substr(char *str, char **endptr, const char *str_dim);


bool readline(char *line, const size_t buffer_len) {
    if (fgets(line, buffer_len, stdin) != NULL) {
        chop_newline(line);
        if (line[0] != NULL) {
            return true;
        }
    }
    return false;
}

bool hasDigits(const char *str) {
    for (size_t i = 0; str[i] != '\0'; ++i) {
        if (isdigit((unsigned char)str[i])) {
            return true;
        }
    }
    return false;
}

bool hasPunct(const char *str) {
    for (size_t i = 0; str[i] != '\0'; ++i) {
        if (ispunct((unsigned char)str[i])) {
            return true;
        }
    }
    return false;
}

void chop_newline(char *str) {
    str[strcspn(str, "\n")] = '\0';
}

char *remove_leading_whitespace(char *str) {
    if (str) {
        while (isspace(*str) &amp;&amp; str) str++; //remove whitespace
    }
    return str;
}

/*
get_substr

@param **endptr, set to next character after a diliminator in string str
@param *str_dim, list of diliminators used to split string ex: " !,.-?"

when called, absorb incoming whitespace ,read until first diliminator, return substring,
and set **endptr equal to the rest of the string. If endptr is not NULL, then string has more to parse,
returns NULL if nothing was parsed else returns c-string
*/

char *get_substr(char *str, char **endptr, const char *str_dim) {
    char *substr = NULL;
    remove_leading_whitespace(str);
    substr = strtok(str, str_dim);
    *endptr = strtok(NULL, "\0");

    return substr;
}

int main() {
    char str_name[MAXSIZE];
    char *last_name = NULL, *first_name = NULL, *endptr = NULL;

    printf("Please enter your first name followed by your last name: ");
    for (;;) {
        if (readline(str_name, sizeof str_name)) {
            if (!hasDigits(str_name) &amp;&amp; !hasPunct(str_name)) {
                break;
            }
            printf("\nTry again, name must contain letters and cannot contain numbers or punctuation...\n");
        }
        else {
            printf("\nEmpty string please try again...\n");
        }
    }

    first_name = get_substr(str_name, &amp;endptr, " ");
    last_name = get_substr(endptr, &amp;endptr, " "); 

    if (endptr) {
        printf("Error, too much input, expected: First name Last name\n %s was not saved...\n", endptr);
    }
    else if (!last_name) {
        printf("Error must have a first and last name...\n");
    }
    else {
        printf("Your name is: %s, %s\n", last_name, first_name);
    }

    printf("Press any key to continue...\n");
    getch();
}
The function is maybe too ambitious in doing two things.

char *get_substr(char *str, char **endptr, const char *str_dim) {
    str = remove_leading_whitespace(str);
    char *substr = strtok(str, str_dim);
    *endptr = strtok(NULL, "\0");
    return substr;
}


I would keep the API simple and leave out endptr.