3

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.

2
  • What would happen if buf == NULL? I tried running a simplified version of code with buf == NULL and got a seg fault because, from what I'm guessing, the loop condition tried to deference a NULL pointer. Is this bad programming practice to have a pointer in the loop condition? Should a loop with a flag condition be utilized instead? Commented Mar 11, 2018 at 22:52
  • buf cannot be NULL after this: buf = delim + 1; Commented Mar 12, 2018 at 6:03

3 Answers 3

3

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'.

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

1 Comment

another approach: (*buf && (*buf == ’ ’)): when *buf==' ' the first condition is true as well so it's redundant all right
1

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 */ 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.

Comments

1

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'.

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.