I'm reading Computer Systems for my CS class and I've come across a while loop condition that's puzzling me, here's the code:
int parseline(char *buf, char **argv)
{
char *delim; /* Points to first space delimiter */
int argc; /* Number of args */
int bg; /* Background job? */
buf[strlen(buf)-1] = ’ ’; /* Replace trailing ’\n’ with space */
while (*buf && (*buf == ’ ’)) /* Ignore leading spaces */
buf++;
/* Build the argv list */
argc = 0;
while ((delim = strchr(buf, ’ ’))) {
argv[argc++] = buf;
*delim = ’\0’;
buf = delim + 1;
while (*buf && (*buf == ’ ’)) /* Ignore spaces */
buf++;
}
In
while (*buf && (*buf == ’ ’)) /* Ignore spaces */
the while
loop has two operands to logical &&
but I don't understand what is the purpose of the first operand (*buf)
. The second operand is checking for empty space, but I would think that the second operand by itself would suffice for the purpose of this loop.
Yes, the *buf &&
is superfluous.
*buf
is false for '\\0'
and true for everything else.
*buf == ' '
is true for ' '
and false for everything else, including '\\0'
.
The following is functionally the same as while (buf == ' ')
if the quote marks '
are changed to '
.
// v-v--- not standard quote marks.
while (*buf && (*buf == ’ ’))
With a good compiler, neither is faster as an optimizing compiler with emit the same code.
To me it is simply pedantic code insuring the loop is not taken with a null character .
What is bad about the code includes:
buf[strlen(buf)-1] = ' ';
is a UB if buf[0] == 0
.
buf[strlen(buf)-1] = ' '; /* Replace trailing '\\n' with space */
buf[strlen(buf)-1] = ' '; /* Replace trailing '\\n' with space */
may lop off a non- '\\n'
.
A better alternative that address the 2 preceding concerns: buf[strcspn(buf, "\\n")] = '\\0';
Instead of "Ignoring spaces", it is more C-like to ignore white-spaces .
"Build the argv list" usually requires a final argv[argc] == NULL
.
Of course these are sides issues to the main question and without the larger context may/may not apply.
The second operand is checking for empty space, but I would think that the second operand by itself would suffice for the purpose of this loop.
while (*buf && (*buf == ’ ’)) /* Ignore leading spaces */
buf++;
It would suffice. The loop would break for *buf == '\\0'
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.