hello everyone, im new in here and im having a headache with my program,the thing is that i need to get a input from the keyboard and then separate it using strtok but have to separate the tokens using 4 diferent cases and in each case i need to print the result and save it to a string like this:

input String : Label Instruction #50,Y; Label <with>

and the output should look like this:

Label: Label
Instruction: Instruction
Character 1: #50
Character 2: Y
Comentaries: Label <with>

also it has to be able to reconize if a instruction is missed like this:

Input String: adda

Output String
Label: -----
Instruction: adda
Character 1: -----
Comentaries: -----

i already got most of the problem but i still cant make the last if statement of "after finding a ; character" i would like to print Comentaries : (any token after a ;) but when i tryed to put it on a if alll i get is a new Character[i]:(anything after the ;) i have tryed for like 2 hrs and i dont know what else can i do to fix this cna some1 please help me?

heres my code:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <ctype.h>
/*
 * ||
 */
int main() {

    char word[256];
    fgets(word,256,stdin);



char *result;


while (result != NULL)
    {

            int i=0;
            char delimit[]="\n , ;";

            result=strtok (word,delimit);

                if (word[0] != 32 && word[0] != 9)

                    {

                    printf("Label \"%s\"\n", result);
                    result = strtok (NULL, "\n , ;");

                    }

            printf("Instruction \"%s\"\n", result);
            result = strtok (NULL, "\n , ;");

                for (i = 0; i < result; i++)
                    {
                        printf("Character [%d]\"%s\"\n",i, result);
                        result = strtok (NULL, ", ;");

                    }
                if(word[0] == 59)
                {


                   printf("Comentaries \"%s\"\n",result);
                    result = strtok (NULL, ";");
                    }
result = NULL;


    }

return(0);
}

Recommended Answers

All 10 Replies

This is a parsing problem, not a simple tokenizing problem. Do you have more details as to the format of the instructions? It looks like you're attempting to write a program that reads assembly-like instructions and break them down into component parts. For that I wouldn't use strtok() as the only solution.

This is a parsing problem, not a simple tokenizing problem. Do you have more details as to the format of the instructions? It looks like you're attempting to write a program that reads assembly-like instructions and break them down into component parts. For that I wouldn't use strtok() as the only solution.

Hello deceptikon,thanks for your reply

yes this is my attempt to try to read a assembly instruction and categorize its parts and i was told strtok() was the easiest way to do it and thats why im using it, but being new to it makes it too hard for me to fully understand it

In mi code I tried to make the strtok() function to tokenizing whenever he finds a (space a coma a semi-colon and a tabspace) and categorize the token in each case with a different print.

First I need to check if the input first character is a “space/s” or “tab/s” if they aren’t it should print “Label” and the token

In the case I get a “space/s” or a “tab/s” at the very first char I need to print “instruction” followed by the token after the “space/s” or “Tab/s”.

The ”character” print should be for the tokens that are separated by a “,” being them 1 or as many as the user inputs(for that I use a for-statement).

Then I need to print “Comnetaries” after strtok() finds a “semi-colon” when it finds it I need to stop tokenizing and print everything after the semi-colon with the print “Comentaries”.

So i only have two scenarios, one with a correct input and one with an incorrent input in witch I should print :

For the correct input:

(any1) (any2) (anyNumber1),(anyNumber2) ;(anything)

Label:any1
Instruction:any2
Character[i]:anynumber1
Character[i]:anyNumber2
Comentaries:anything

As for the incorrect output I should print

(space) (space) (anyNumber1)

Label:-------------
Instruction:anyNumber
Character[i]:-----------------
Comentaries:----------------

As you can see this is where Im having all the troubles since I don’t know how should I do it correctly.
As a note: Im using strtok() because I was told it was the easier way to make the tokens and then categorize them but so far im not able to,also im not very good at programming in C and that’s why my code is full of incoherences I would appreciate any help you can give me

The problem is that strtok() won't tell you when a token isn't present, so you need some extra logic to identify tokens either by special characteristics or by expected position. Comments are easy because they're always led by a semicolon, but the others can be tricky. For example, if both the label and instruction can be any string, how do you know if you got a label but no instruction or an instruction but no label?

You explained what you're trying to do quite nicely, but that wasn't what I asked for. I asked for details about the assembly format. I hope that your instructor didn't invent something ambiguous that's difficult to parse, because that would just be cruel.

well the assembly format as you say i think you mean the input that the teacher is gona try? well it a correct one would be a :

(Label)(space)(instruction)(space)(number),(number)(;)(comentaries)

but the input has the posibility of having a space/s or a tab/s at the begining in withc cause my program would have to take it as if no layer was input and goes directly to the instruccion for the first character after the space/s Tabs/s

like this:

(space/s or Tab/s)(Instruction)(space)(number),(number)(;)(comentaries)

i hope this was what your refering to, and the problem is i cant figure out wich logic should i use to be able to categorize the tokens in order to being able to display a bad input
hope this help cause im out of ideas

In normal syntax, optional values are surrounded with [ ], required are not. And, for this discussion, # will designate one or more SPACEs/TABs.
What I understand then is you can have the following:

[Label] # Instruction # number1,number2 # [; comment]

So:
A label cannot be preceeded by # and is optional

An instruction must be
1) preceeded by at least one #
2) followed by at least one # and number1

Both numbers are required in the format number1 comma number2 (are spaces allowed?)

The comment is completely optional.

If this is not correct (there are other optional parts), please update using the above syntax.

To your questions, YEEESSSS exactly that you nailed it i couldn't explained better yes indeed the only diference is that on number
2)Followed by at least one # and numer both numbers are requiered in the format number1 comma nunber

Hello WaltP thanks for yourn replly

and this would be

2) followed by at least one # and number1
Both numbers are required in the format number1 comma number2 comma (and i make this a cicle because on a wrong input it could have alot of number separate by alot of comas)
to you question (are spaces allowed?):the anwser is no, if a space or tab is detected after a coma it should print "------" or NULL on the Character [i] (i = number of times the number was followed by a coma) and then the proces would be ended also making Comentaries "--------" or NULL

And finally yes the Coment is completely opcional
i wish this information was more clear thanks WaltP

Do you know about functions? Assuming you do, I see some that would be very helpful:

1) int spanSpaces(line, index)
This will start at line[index], skip all 'whitespace' (look up the function isspace()) and return the index of the next non-space character.

2) int spanText(line, index)
Same, but skips all text values, for Label and Instruction. Are numbers allowed in the abel or Instruction? If so, isalnum() is the function to use, otherwise isalpha()

3) int spanNumber(line, index)
Again, same but skips numbers (isdigit())

Using theis idea, starting before INSTRUCTION you might do:

if current character (line[index]) is a space, 
    call spanSpace()
    store index in instBegin
    call spanText() with instBegin
    store index in instEnd
    copy the characters from instBegin to instEnd-1 into the instruction
If current character (line[index]) is a space, 
    call spanSpace()
    store index in numBegin
    ...

Just string the calls with appropriate tests before/after each call. You know what characters to expect after each field. Make sure they are there.

Of course you have to start with LABEL

Do you HAVE to use strtok()? If not, try some different methodology. Why? Because strtok() will alter the string being processed, inserting a null byte at the end of each token returned. In any case, it will return NULL when there are no more tokens to return. I have used it in the past, but often found that it was unsuitable for what I was trying to do. Why? Because if you are processing quote-delimited strings as one example, and there is a delimiter character inside a string that you want to keep intact, you are quickly hosed!

When I was writing a parser for a major application framework that had to read a TCL-based string that represented a hierarchy of C++ objects, I tried using strtok() to tokenize the string. I quickly found this problem and had to roll my own tokenizer. It was effective, and is still in use today in software that runs most semiconductor fabs in the world.

thank you very much for your advice waltP
i liked your idea alot so i started to make it yesterday but my knowldge in functions is pretty basic and after the whole day of test i insert the functions you recomended me on my code but i wasnt able to string the calls correctly giving me no result as i think i make my functions wrong this is my funtions code

#include <stdio.h>
#include <string.h>
#define MAX 256
int main(void){

    char word[MAX];
    scanf("%s",word);
    //scanf("%d",input);
    int i=0;

char *result;

int isspace(word,c)
{
    char str[MAX];
    int i=0;

    while (str[i])
        {
    c=str[i];

    if (isspace(c)) c='\n';
    putchar (c);
    i++;
        }
    return c;       //return the answer
}

int isalnum(word,c)
{

        char str[MAX];
        int i=0;

        while (str[i])
        {
        c=str[i];

        if (isalnum(c)) c='a-z';
            putchar (c);
            i++;
        }
    return c;
}

int isdigit(word,c)
{
    char str[MAX];
        int i=0;

        while (str[i])
        {
        c=str[i];

        if (isdigit(c)) c='0-9';
            putchar (c);
            i++;
        }
    return c;
}
while (word[i]);
    {
                if (word[i] == 32 && word[0] == 9)
                    {
                            isspace();
                            c=instBegin;
                            isalnum();
                            c=instEnd
                            /*
                            printf("Label \"%s\"\n", result);
                    result = strtok (NULL, "\n , ;");
                    }

            printf("Instruction \"%s\"\n", result);
            result = strtok (NULL, "\n , ;");

                for (i = 0; i < result; i++)
                    {
                        printf("Character [%d]\"%s\"\n",i, result);
                        result = strtok (NULL, ", ;");
                    }
                if(word[0] == 59)
                {
                   printf("Comentaries \"%s\"\n",result);
                    result = strtok (NULL, ";");
                    }

    }
*/

return 0;
}

i followed the instructions i read on each of the functions you recomended me an tried to make them in my code but after i made the functions i have no clue how to make the string calls or is they even correct :/ and i cant continue
any help or advice will be appreciated

1) I said use isspace(), not write it. You use it in a function called (for example) skipSpaces() or spanSpace() as I called it originally.

I'll give you a start:

int spanSpace(char *str, int idx)
{
    while (isspace(str[idx]))  // as long as current character is a space...
        idx++;                 // skip it.
    return idx;                // return the new index, poins to a non-space
}

Now research isspace() and the others to see how they are used.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.