teronuppi22
teronuppi22

Reputation: 1

Split user inputted string to char array

I'm making an appointment calendar program with c. My program adds an new appointment with user inputted command: "A 'description' 'mm' 'dd' 'hh'" Where description is a string with a maximum of 20 characters, mm is months, dd is days and hh is hours. Months, days and hours can be 1 or 2 characters long. I have tried to implement readInput function which splits the input string by spacebar and returns a char array which contains: [description, mm, dd, hh] so I can easily get:

desc = array[1];
month = array[2];
day = array[3];
hour = array[4];

Implementing this function was harder than I thought and I have failed miserably. I don't want pointers, just a basic char array containing strings. How should I implement this? Below is my main function.

int main()
{   
    struct Calendar c;
    c.numOfAppointments = 0;
    while (true) {
        char str[30];
        printf("Command: ");
        scanf("%[^\n]%*c", str);
        if (str[0] == 'A')
        {
            char command = readInput(str); /*implement this */
        }
        else if (str[0] == 'L')
        {
            printCalendar(c);
        }
        else if (str[0] == 'Q')
        {
            printf("Exiting program...");
            break;
        }
    }
}

Say I input: A dentist 4 20 10

the returned array should be: ["dentist","4","20","10"]

Upvotes: 0

Views: 61

Answers (2)

user9706
user9706

Reputation:

Use fgets(str, strlen(str), stdin) to read in your string. The next step is is to parse the string. As your input consist of a variable description followed by a somewhat variable date time format. The way to parse is to start at the end to find the separator sep between description and month which would be the 3rd last space (n = 2). You now know whatever is before sep is "A " prefix and description, and everything after is the date time. You can use strptime(3) to parse the date time:

#define _POSIX_C_SOURCE 200809L
#define _XOPEN_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

int rindexn(const char *s, char c, size_t n) {
    int i = strlen(s);
    if(!i) return -1;
    for(i--; i >= 0; i--) {
        if(s[i] == c) {
            if(!n) break;
            n--;
        }
    }
    return i >= 0 ? i : -1;
}

int main() {
    const char *str = "A dentist 4 20 10";

    // parse
    if(!strncmp(str, "A ", 2)) {
        printf("A space prefix missing");
        return 1;
    }
    int sep = rindexn(str, ' ', 2);
    if(sep == -1) {
        printf("sep not found\n");
        return 1;
    }
    struct tm tm;
    char *end = strptime(str + sep + 1, "%m %d %H", &tm);
    if(!end) {
        pritnf("cannot parse date time\n");
        return 1;
    } else if(*end) {
        printf("extra data after hour\n");
        return 1;
    }

    // convert to whatever format you decide
    printf("description = \"%.*s\", month = %d, day = %d, hour = %d",
        (int) sep - 2, str + 2, tm.tm_mon, tm.tm_mday, tm.tm_hour);
}

which gives the following output:

description = "dentist", month = 3, day = 20, hour = 10

Upvotes: 0

einpoklum
einpoklum

Reputation: 131970

Implementing this function was harder than I thought and I have failed miserably.

Don't be so hard on yourself... you're learning. We learn to program mainly through our mistakes :-)

I don't want pointers, just a basic char array containing strings.

Ah, so, there's your problem: Will it be an array of characters, or an array of strings?

A string in C is a pointer to a sequence of characters in memory ending with a \0.

An "array of strings" is an array of pointers!

What you could do is:

  1. Read your line into a proper array of characters.
  2. Place '\0' at appropriate places in this array, to indicate the end of line components.
  3. Have a second array, e.g. const char * array_of_fields[4], whose elements are strings.

or

  1. Have a struct { const char* description, month, day, hour; }

and then

  1. Set the elements of the second array, or the elements of the struct, to point to the appropriate positions within the character array.

Upvotes: 1

Related Questions