J_code
J_code

Reputation: 347

Make fgets skip special character

My question is about parsing a text file using fgets. Basically there are commands that I need to parse. Once I hit a ";", anything afterwards are comments and can be skipped:

;;
;; Very basic test - no ifs or comparisons
;;

defun main
5 3 2 * + printnum endl     ;; Should output (3 * 2) + 5 = 11
3 4 5 rot * + printnum endl ;; Should output (3 * 5) + 4 = 19
return

After processing:

defun main
5 3 2 * + printnum endl     
3 4 5 rot * + printnum endl 
return

In my code, I have a while loop to get each line from the text file:

while (fgets(str, 1000, IN)!= NULL)
        {
            len = strlen(str);
            str[len-1] = '\0'; //removes newline character
            printf("%s\n", str);
            hello = strtok(str,";");
            printf("%s\n", hello);

        }

I'm unsure as to how to make it where, when strtok sees a semicolon, it will automatically cut out anything that comes after, up until the end of the line. My attempt returns the following output:

 Very basic test - no ifs or comparisons


defun main
5 3 2 * + printnum endl     
3 4 5 rot * + printnum endl 
retur

It cuts off the last character from return but doesn't remove the comment after the second line of semicolons. This is pretty standard behavior no matter the contents of the text file I'm parsing. What am I missing here? Thank you.

Upvotes: 0

Views: 887

Answers (1)

melpomene
melpomene

Reputation: 85887

The problem comes from strtok. As man strtok says:

The strtok() function breaks a string into a sequence of zero or more nonempty tokens.

[...]

From the above description, it follows that a sequence of two or more contiguous delimiter bytes in the parsed string is considered to be a single delimiter, and that delimiter bytes at the start or end of the string are ignored.

(Emphasis mine.)

Whenever your line starts with one or more ; characters, strtok will simply ignore them.

To solve this, you should instead search for the first occurrence of ; in the string, and if found, replace it by '\0' (the NUL terminator).

Variant 1 (using strchr / if):

char *p = strchr(str, ';');
if (p) {
    *p = '\0';
}
printf("%s\n", str);

Variant 2 (strcspn, cheeky):

str[strcspn(str, ";")] = '\0';
printf("%s\n", str);

Upvotes: 1

Related Questions