- Make sure you can identify the limits of what you print when you're printing.
- Output newlines at the end of printed messages; the information is more likely to appear in a timely manner if you do that.
- Don't print NULL pointers as strings; not all versions of
printf()
will behave nicely — some of them dump core.
Code:
#include <stdio.h>
#include <string.h>
int main(void)
{
char abc[] = "ls &";
char *tok;
char *ptr = abc;
while ((tok = strtok(ptr, " ")) != NULL)
{
printf("<<%s>>\n", tok);
ptr = NULL;
}
return 0;
}
Or (optimized, courtesy of self.):
#include <stdio.h>
#include <string.h>
int main(void)
{
char abc[] = "ls &";
char *tok = abc;
while ((tok = strtok(tok, " ")) != NULL)
{
printf("<<%s>>\n", tok);
tok = NULL;
}
return 0;
}
Output:
<<ls>>
<<&>>
You can choose your own marker characters, but when not messing with XML or HTML, I find the double angle brackets reasonably good for the job.
You can also use your loop structure at the cost of writing a second call to strtok()
(which is a minimal cost, but might be argued to violate the DRY principle: Don't Repeat Yourself):
#include <stdio.h>
#include <string.h>
int main(void)
{
char abc[] = "ls &";
char *tok = strtok(abc, " ");
while (tok != NULL)
{
printf("<<%s>>\n", tok);
tok = strtok(NULL, " ");
}
return 0;
}
Same output.
Revised requirement
I would like to add a printf()
statement outside the while
loop and print '&
' outside. I need it since I want to compare it later with another variable in the program. Is there any way to do so?
Yes, there is usually a way to do almost anything. This seems to work. It also works sanely if there are more tokens to parse, or if there's only the &
to parse, or if there are no tokens. Clearly, the body of the outer loop could be made into a function if you so wished; it would be sensible to do so, even.
#include <stdio.h>
#include <string.h>
int main(void)
{
char tests[][16] =
{
"ls -l -s &",
"ls &",
"&",
" ",
""
};
for (size_t i = 0; i < sizeof(tests)/sizeof(tests[0]); i++)
{
printf("Initially: <<%s>>\n", tests[i]);
char *tok1 = strtok(tests[i], " ");
char *tok;
while ((tok = strtok(NULL, " ")) != NULL)
{
printf("Loop body: <<%s>>\n", tok1);
tok1 = tok;
}
if (tok1 != NULL)
printf("Post loop: <<%s>>\n", tok1);
}
return 0;
}
Output:
Initially: <<ls -l -s &>>
Loop body: <<ls>>
Loop body: <<-l>>
Loop body: <<-s>>
Post loop: <<&>>
Initially: <<ls &>>
Loop body: <<ls>>
Post loop: <<&>>
Initially: <<&>>
Post loop: <<&>>
Initially: << >>
Initially: <<>>
Note how the markers pay for themselves in the last two examples. You couldn't tell those apart without the markers.
while
loop continues untiltok
isNULL
, right? So in the secondprintf
statement,tok
isNULL
. Is that surprising? – Astreastrtok()
you can always consult the documentation. – Merousprintf()
? And since you wrote this, what do you thinkprintf("\n\n\n\n\n%s", NULL);
will do, since you're guaranteed that will be what is executed? Get rid of the secondprintf
and just print each token until there are no more. – Merousstrcmp(tok, "&") == 0
. If you wait untiltok == NULL
, then the second printf doesn't have anything to print. – Lantern