0

I'm having trouble wrapping my mind around parsing user input in c. My task (homework) is to read user input, then parse in the same way BASH does, so delimiters are ' ', |, >, etc. My (wrong) solution so far uses strtok. I've been advised to use sscanf, but haven't been able to wrap my mind around how that will work for all cases of user input.

I'd love a strategy that will point me in the right direction. Here's what I have so far:

#include <stdio.h>
#include <unistd.h>
#include <string.h>

#define MAX_LINE 80


int main ()
{

    const char delim[]=" \\|\\>\\1>\\2>\\>>\\2>>\\&>\\<";

    char* args[MAX_LINE/2 + 1];
    char tok[MAX_LINE];
    char* token;

    printf("osh>");

    fgets(tok, sizeof(tok), stdin);

    token = strtok(tok,delim);

    while (token != NULL)
    {   
        printf("%s\n", token);

        token = strtok(NULL, delim);
    }            

    return 0;

}
4
  • 1
    If your goal is just to split up the line using the delimiters then I think you're on the right track. What problems are you having with your existing solution? Commented Mar 6, 2014 at 2:55
  • I split at those delimiters, but I need to retrieve them. So imagine input like: gedit HW>txt Commented Mar 6, 2014 at 2:58
  • Ah! Right, strtok will not tell you which delimiter was matched. So if you need the delimiter then that won't work as you found out. I'll post an answer with a few suggestions. Commented Mar 6, 2014 at 3:10
  • What are "\\|\\>\\1>\\2>\\>>\\2>>\\&>\\<" supposed to be ? The C string equivalent of \|\>\1.\2>\>>\2>>\&>\< ? You can't use strtok to split on multi-char delimiters. It looks like you're trying to encompass a limited DFA in a single strtok call, but that can only be done if the delimiters are all single-chars. Commented Mar 6, 2014 at 3:10

2 Answers 2

2

Method 1) You can use pointer arithmetic to locate the delimiter while still using strtok to extract the delimited strings. This seems to me the easiest solution but requires pointer arithmetic. Be sure you don't try to access 'tok' beyond the end of the array or before the array (by over-decrementing the pointer).

Example:

token = strtok(tok, delim);
char verb = *token--;

Method 2) You could use sscanf in the same manner looking for strings, then single characters, then strings... and so forth till you hit the end of the line.

For either method you need to store the strings and delimiters somewhere and maintain the order so you can reconstruct the sequence.

Good luck.

Sign up to request clarification or add additional context in comments.

Comments

0

Thanks for the help on this. I ended up going a different route entirely, basically keeping track of the contents of each index of the fgets result, then parsing from there. I didn't end up using any c-ish methods (i.e. strtok) to do the job.

Here's a sample snippet.

        {
            //integers correspond to ASCII values
            LEN++;
            if ((line[i+1] == 60) || (line[i+1] == 62) || (line[i+1] == 124) || (line[i+1] == 38) || (line[i+1] == 32) || (line[i+1] == 10))
            {
                memcpy(substring, &line[string_start], LEN);
                substring[LEN] = '\0';
                args[token_number] = malloc(strlen(substring) + 1);
                strcpy(args[token_number], substring);

                token_number++;
                string_start = i+1;
                LEN = 0;  
            }

            i++;
        }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.