#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2016
    Posts
    5
    Rep Power
    0

    Why isn't my code working the way I need?


    This program is supposed to take input and then print the sentence in reverse but for some reason, it's not progressing beyond the input loop.


    Code:
    #include <stdio.h>
    #define printf __mingw_printf
    
    int main()
    {
    	short i = 0, m = 0, n = 0;
    	char revSentence[256];
    	unsigned char letter;
    	
    	printf("Enter a sentence: ");
    	do
    	{
    		revSentence[i] = letter = getchar();
    		i++;
    	}
    	while (letter != 63 || letter != 33 || letter != 46 || letter != '\n');
    	
    	printf("\nReversal of your sentence is: ");
    	for (m = i; i >= 0;)
    	{
    		m = i;
    		do
    		{
    			if (i == 0)
    			{
    				putchar(revSentence[i]);
    				goto endProgram;
    			} 
    			letter = revSentence[i];
    			i--;
    		}
    		while (letter != 32);
    		
    		for (n = (i+1); n <= m; n++)
    		{
    			putchar(revSentence[n]);
    		}
    		i--;
    	}
    	
    	endProgram:
    	return 0;
    }
  2. #2
  3. Contributing User
    Devshed God 1st Plane (5500 - 5999 posts)

    Join Date
    Aug 2011
    Posts
    5,843
    Rep Power
    509
    letter has a single value in the test
    (letter != 63 || letter != 33 || letter != 46 || letter != '\n')
    hence at least 3 of these inequalities are true,
    hence it's always true.
    Change the `or's to `and's.

    This will make you happy and your program will usually run along and finish and you'll find other problems and fix them and you'll think you have a great program.

    However, were the input to contain more then 256 word-like characters the revSentence buffer would overflow and world war III might begin. This test we've mentioned should include a length test as well.
    And if the file ended you wouldn't know because getchar returns int which you decapitate to unsigned char. EOF is -1 on my system.

    Were it my program I'd be satisfied replacing that input loop with fgets. You could instead use scanf with a character set class, and the length limit.

    Comments on this post

    • AamirYousafi agrees : Great!
    • Will-O-The-Wisp agrees : Thank you!
    [code]Code tags[/code] are essential for python code and Makefiles!
  4. #3
  5. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2016
    Posts
    5
    Rep Power
    0
    b49P23TIvg, thanks for your help and suggestions. The program works fine now. Just for the sake of completeness, I have included the source code below.

    Code:
    #include <stdio.h>
    #define printf __mingw_printf
    
    int main()
    {
    	/* declarations */
    	short i = 0, j = 0, m = 0, n = 0;
    	unsigned char revSentence[256];
    	unsigned char letter;
    
    
    	/* sentence input */
    	printf("Enter a sentence: ");
    	do
    	{
    		revSentence[i] = letter = getchar();
    		i++;
    		if (letter == 63 || letter == 33 || letter == 46)
                break; /* getchar will stop taking input (after an Enter press, of course)
                        if an exclamation, question, or period is input */
    	}
    	while (letter != EOF);  // think this is necessary for getchar() but don't quite get why it's necessary
    	revSentence[i] = '\0'; // adding the null character
    	j = --i; // marker for the exclamation / question mark or period
    
    
        /* sentence reversal and printing */
    	printf("\nReversal of your sentence is: ");
    	while (i >= 0)
    	{
    		m = (i - 1);
    		do
    		{
    			letter = revSentence[--i];
    		}
    		while (letter != 32 && i > 0);
            if (i == 0)
                i--;
    		for (n = (i+1); n <= m; n++)
    		{
    			putchar(revSentence[n]);
    		}
    		printf(" ");
    	}
    
    	printf("\b");
    	putchar(revSentence[j]); // printing the exclamation / question mark or period
    	printf("\n\n");
    
    	return 0;
    }
  6. #4
  7. Contributing User
    Devshed God 1st Plane (5500 - 5999 posts)

    Join Date
    Aug 2011
    Posts
    5,843
    Rep Power
    509
    Better, but still not right.
    Code:
    $ echo hi there molly. | ./c
    echo hi there molly. | ./c
    Enter a sentence: 
    Reversal of your sentence is: molly there hi.
    $ echo hi there molly | ./c
    Segmentation fault (core dumped)
    $
    [code]Code tags[/code] are essential for python code and Makefiles!
  8. #5
  9. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2016
    Posts
    5
    Rep Power
    0
    That's exactly what it's supposed to do.
  10. #6
  11. Contributing User
    Devshed God 1st Plane (5500 - 5999 posts)

    Join Date
    Aug 2011
    Posts
    5,843
    Rep Power
    509
    Core dump?????
    $ echo hi there molly | ./c
    Segmentation fault (core dumped)
    $

    Comments on this post

    • oldcodeworks agrees
    • hexman agrees
    [code]Code tags[/code] are essential for python code and Makefiles!
  12. #7
  13. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2016
    Location
    S.E. Washington state
    Posts
    11
    Rep Power
    0
    You have a memory problem after the reverse sentence is printed. That is a big problem. Just because you got the program to provide the data the way you expect means nothing unless the program closes properly.
    Your program is crashing before it reaches the end.
  14. #8
  15. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2016
    Posts
    5
    Rep Power
    0
    Originally Posted by oldcodeworks
    You have a memory problem after the reverse sentence is printed. That is a big problem. Just because you got the program to provide the data the way you expect means nothing unless the program closes properly.
    Your program is crashing before it reaches the end.
    So, I guess, the question is, why is it doing this? Is it because of getchar or something else? Is it my logic that is wrong? Some keywords that I shouldn't have used. What exactly, if you can point it out.
  16. #9
  17. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2014
    Location
    India
    Posts
    200
    Rep Power
    4
    Originally Posted by AamirYousafi
    So, I guess, the question is, why is it doing this? Is it because of getchar or something else? Is it my logic that is wrong? Some keywords that I shouldn't have used. What exactly, if you can point it out.
    See the last line there:

    Code:
    putchar(revSentence[j]); // printing the exclamation / question mark or period
    You've written it yourself -- "printing the exclamation / question mark or period" -- you're making assumptions and assumptions are never good. You're assuming that the input will always contain an exclamation mark, question mark or period and when it doesn't, well, your program crashes as you're trying to access the memory that doesn't exist. I don't have the time to narrow it down where the revSentence messes up or why. It seems that when you set the value of j as the index for the exclamation mark or other symbols but your input doesn't contain it, j will index a number which is out of bounds for revSentence thus crashing your program.

    Code:
    24    j = --i; // marker for the exclamation / question mark or period
    If you take out 'j' and line 47 altogether and replace the if clause on line 16 with "if (letter == '\n')" then your program will not segfault on an input which doesn't contain the assumed symbols but it won't print them correctly for those which do contain them.

    For example:

    Code:
    $ echo say my name! | ./prog
    Enter a sentence: 
    Reversal of your sentence is: name my say!
    $ echo say my name | ./prog
    Segmentation fault (core dumped)
    
    $ echo say my name | ./modifed_prog
    Enter a sentence: 
    Reversal of your sentence is:  name my say
    $ echo say my name! | ./sample
    Enter a sentence: 
    Reversal of your sentence is:  name! my say
    It's probably because of the way you take input from the user and handle it. The current program preserves the symbol on the end but it still doesn't give satisfactory results when confronted with unprecedented input.

    For example:

    Code:
    $ echo 'say my name!!' | ./sample
    Enter a sentence: 
    Reversal of your sentence is: name my say!
    There are better ways to do this but if your program does what you want to do and you don't want to deal with corner cases and unknown input then keep it like this but if you want to learn to develop quality programs then you should certainly improve this.

    Comments on this post

    • Will-O-The-Wisp agrees : Thank you!
    Last edited by hexman; July 14th, 2016 at 05:57 AM. Reason: used CODE tags for terminal output.

IMN logo majestic logo threadwatch logo seochat tools logo