0

I have written two codes for splitting sentences to words, one of which worked while other one didn't. Only difference is in the if condition under for loop. First one gave no output. While second one is giving expected output. Please explain logically, don't teach DeMorgan Laws. I have purely applied my logic in both of them which I think is also correct in first code.

NOT WORKING ONE:

  #include <stdio.h>
  void main(void){
  int i=0, m=0, n=0, j, l=0;
  char sen[500], wrd[500][500];

  printf("Input a sentence:\n");
  gets(sen);

  while(sen[i]!='\0'){
  l++;
  i++;
  }

  for(i=0;i<=l;i++){
    if(sen[i] != ' '||sen[i] != '\0'){    //Here is the difference.
        wrd[m][n]=sen[i];
        n++;
    }
    else{
        wrd[m][n]='\0';
        puts(wrd[m]);
        printf("\n");
        m++;
        n=0;
    }
    }
}

WORKING ONE:

 #include <stdio.h>
 void main(void){
 int i=0, m=0, n=0, j, l=0;
 char sen[500], wrd[500][500];

 printf("Input a sentence:\n");
 gets(sen);

 while(sen[i]!='\0'){
 l++;
 i++;
 }

 for(i=0;i<=l;i++){
    if(sen[i] == ' '||sen[i] == '\0'){        //Here is the difference.
        wrd[m][n]='\0';
        puts(wrd[m]);
        printf("\n");
        m++;
        n=0;

    }
    else{
        wrd[m][n]=sen[i];
        n++;
    }
    }
}

Only difference is in the if condition of for loop. First one have: if(sen[i] != ' '||sen[i] != '\0') Second have: if(sen[i] == ' '||sen[i] == '\0')

Vartika
  • 77
  • 1
  • 6

4 Answers4

3

You seem to be under the impression that the condition:

(sen[i] != ' '||sen[i] != '\0')

is the logical negation of:

(sen[i] == ' '||sen[i] == '\0')

That is not the case. DeMorgan's Laws dictate the logical equivalence of boolean statements.

The general case of what you want is !(A || B) == (!A && !B). So you can move a negation inside of a grouped expression, but a logical OR turns into a logical AND, and vice versa.

In your specific case, the inverse of the latter condition is:

!(sen[i] == ' ' || sen[i] == '\0')

Which becomes:

(sen[i] != ' ' && sen[i] != '\0')

Talking through this, you want to append to wrd if both sen[i] is not a space AND sen[i] is not a newline. You instead said you want to append to wrd if either sen[i] is not a space OR sen[i] is not a newline. Any character is either not a space or not a newline, so this condition will always be true.

dbush
  • 205,898
  • 23
  • 218
  • 273
  • But I didn't get the logic. I have known de Morgan laws for a long time. But can you explain how it works in my particular code. – Vartika Oct 25 '18 at 19:14
  • @Vartika You applied negation to each subexpression but failed to switch `||` to `&&`. That was your mistake. – dbush Oct 25 '18 at 19:15
  • Can you explain logically? How my first code went wrong? Forget that I have written second code and demorgan laws. I have not used demorgan law in any of them. I have just used only my logic which I think is alao correct with first code. – Vartika Oct 25 '18 at 19:19
1

Here are the equivalences:

if(sen[i] == ' '||sen[i] == '\0'){
  // code block #1
} else {
  // code block #2
}

is logically equivalent to the following:

if(sen[i] != ' ' && sen[i] != '\0'){
  // code block #2
} else {
  // code block #1
}

Basically when you inverted individual conditions you neglected to also change the OR into AND.

YePhIcK
  • 5,816
  • 2
  • 27
  • 52
  • But I didn't get the logic. I have known de Morgan laws for a long time. But can you explain how it works in my particular code. – Vartika Oct 25 '18 at 19:14
  • Can you explain logically? How my first code went wrong? Forget that I have written second code and demorgan laws. I have not used demorgan law in any of them. I have just used only my logic which I think is alao correct with first code. – Vartika Oct 25 '18 at 19:19
1

First one gave no output because if(sen[i] != ' '||sen[i] != '\0') always evaluates to True.
Ok, I will try to explain you logically without going through DeMorgan Laws. Suppose a string is entered:
This is a string.
Control will go through the loop.
Consider i=3, at indexing 3 character is 's' (sen[3]='s').
Now, if condition will be checked.
sen[3] != ' ' == True
sen[3] != '\0' == True
Now, if(sen[i] != ' '||sen[i] != '\0') >>> True||True >>> True.
So, body of if block will be executed. Hence, no output.
Now i=4, at indexing 4 character is ' ' (sen[3]=' ').
Now, if condition will be checked.
sen[4] != ' ' == False
sen[4] != '\0' == True
Now, if(sen[i] != ' '||sen[i] != '\0') >>> False||True >>> True. Again, body of if block will be executed. Hence, no output.
else block will never be executed which contains statements for output. More logically, You want to append to wrd if either sen[i] is not a space OR sen[i] is not a null-character. Every character is either not a space or not a newline, so this condition will always be true. In your logic, else blok will be executed only when such character is encountered which is both space and \0(null). Since such character does not exist else block in your code will never execute. Hence, NO OUTPUT.

GIRISH
  • 101
  • 1
  • 8
0

About the logic in your code, in the code which is NOT working, in the sentence:

if(sen[i] != ' '||sen[i] != '\0'){ 

If an empty space was found you get the first parameter as a false, but the second one compares against the end of the string, but it's NOT equal! So this comparison becomes true... false or true gives you true... So the code do what you are expecting to do with a char or a word

D Adalid
  • 33
  • 1
  • 4