Search code examples
cstringnullcomparespace

how to make a string loop stop with space or null in C?


while((str[i] != ' ') has as exit 112
while((str[i] != '\0') has as exit 112 12
while((str[i] != ' ') || (str[i] != '\0')) would be 112 but it's burst o str and is not leaving the loop

#include <stdio.h>
#include <string.h> 

int main(int argc, char *argv[]){

    char str[] = {"112 12"};
    int i = 0;

    while((str[i] != ' ') || (str[i] != '\0')){    /*  it bursts vector  */
        printf("%c", str[i]);
        i++;
    }

    return 0;
}

Solution

  • I'll leave this as an answer, since De Morgan is so useful for issues like this. The conversion in question that makes the problem easier to see in the original code is:

    (not A) or (not B) == not (A and B)
    
    (str[i] != ' ') || (str[i] != '\0') <equivalent> !(str[i] == ' ' && str[i] == '\0')
    

    Since (A && B) will always be false (str[i] cannot be both a space and a terminator), the inverse, i.e. !(A && B) will always be true, so the while condition never evaluates to false, and you get infinite looping. This is easier to see with the latter statement (hence the usefulness of De Morgan).

    Note also that the corrected statement (see FaisalM answer) can also be restructured, using the other De Morgan conversion:

    (not A) and (not B) == not (A or B)   
    
    (str[i] != ' ') && (str[i] != '\0') <equivalent> !(str[i] == ' ' || str[i] == '\0')
    

    This also makes (for me at least) easier interpretation while reading the second version: it's a space, or if it's a null terminator, make it false with !, kills the while loop.

    However now you have to evaluate the full expression inside the parenthesis... which might cause some efficiency losses, see short-circuiting evaluations... although I think the compiler generally does the conversion back to the more efficient version automatically.