[C programming] palidrome checking

Discussion in 'Mac Programming' started by gotenks05, Dec 12, 2009.

  1. gotenks05 macrumors member

    Joined:
    Jan 1, 2009
    #1
    I am trying to make a program that takes a user inputted string and checks to see if it is a palidrome. I got it wrote out, but there is one problem. First, the string is not displayed. When the function I made checks through a string, it always evaluates the statement to either true, that it is a palidrome, or false, that it is not a palidrome, when the opposite result was true. For example, "Madam Im Adam" always evalutes to false in my current code and in a different implementation, "Hello World!" always evaluated to true. What am I doing wrong?

    Here is the program source:

    Code:
    #include <stdio.h>
    #define Size 700
    #include "stringcheck.h"
    int main()
    {
    	char line[Size];
    	int check;
    
    	printf("Enter a string:  ");
    	fgets(line, Size, stdin);
    
    	check = stringcheck(line);
    
    	if (check == 0)
    	{
    		printf("\"%s\" is not a palindrome\n", line);
    	}
    
    	else
    	{
    		printf("\%s\" is a palindrome\n", line);
    	}
    
    	return 0;
    }
    Here is my custom header source:
    Code:
    int stringcheck(char string[]);
    And here is the function definition:

    Code:
    #include <stdio.h>
    #include <string.h>
    #include <ctype.h>
    #define false 0
    #define true 1
    int stringcheck(char string[])
    {
    	int size = strlen(string);
    	int count = size -2, count2 = 0, count3 = size -1;
    	int display;
    	char reverse[size];
    
    	for (count2; count2 <= size -1; count2++)
    	{
    		reverse[count2] = string[count3];
    		count3--;
    	}
    
    	for (display = 0; display <= count; display++)
    	{
    		if (reverse[display] == string[count] | reverse[display] == toupper(string[count]) | reverse[display] == tolower(string[count]))
    		{
    			return true;
    		}
    
    		count--;
    	}
    
    	return false;
    }
    I have a feeling that my problem rests in the definition and the source for both the main program and the function definition. I tried to do a loop that checks different positions of an array instead of using two different arrays and the result is still the same.

    Update: I have fixed the problem, but now there is a new one. I now get a segementation fault on the string "Madam Im Adam".

    Here is the updated function definition:

    Code:
    #include <stdio.h>
    #include <string.h>
    #define false 0
    #define true 1
    int stringcheck(char string[])
    {
    	int size = strlen(string);
    	int count = size -1, count2 = 0;
    	char reverse[size];
    
    	while (count2 != count)
    	{
    		reverse[count2] = string[count];
    		count2++;
    		count--;
    	}
    
    	if (strcmp(reverse, string) == 0)
    	{
    		return true;
    	}
    
    	else
    	{
    		return false;
    	}
    }
     
  2. Detrius macrumors 68000

    Joined:
    Sep 10, 2008
    Location:
    Asheville, NC
    #2
    First of all, this reeks of a homework assignment, so there are limits to what I'll do to help.

    Next, check the manpage for strlen. The value you're expecting is not the value it's giving you.

    Also, strcmp isn't going to do the work for you. "Madam Im Adam" reverses into "madA mI madaM", which strcmp is going to say are not the same strings--because they aren't.


    Lastly, I'm surprised this compiles at all:

    Code:
    	int size = strlen(string);
    	[COLOR="Blue"]char reverse[size];[/COLOR]
    At least when I learned C and C++ (things may have changed), you can't allocate a dynamically sized array on the stack like that. You have to do it in the heap using either "malloc" or "new."
     
  3. mslide macrumors 6502a

    Joined:
    Sep 17, 2007
    #3
    C99 allows variable length arrays. C++ does not although some compilers (e.g. g++) will allow it and compile it. Personally, I don't like using VLAs and usually don't, even if a standard allows it.
     
  4. xStep macrumors 68000

    Joined:
    Jan 28, 2003
    Location:
    Less lost in L.A.
    #4
    Detrius beat me to it but here is another.

    Looks to me like your while loop would be endless on even length strings greater than 2 characters, and on odd length length strings greater than 1 character would only copy half of the string to the reverse variable. Where the string is a length of 1, the while loop will not copy the string. Go back to using a for loop.
     
  5. Detrius macrumors 68000

    Joined:
    Sep 10, 2008
    Location:
    Asheville, NC
    #5
    Well, I learned it in '98, so that would explain it. :D I've gotten my C++ skills up-to-date but apparently I'm still a bit outdated on C.
     
  6. Detrius macrumors 68000

    Joined:
    Sep 10, 2008
    Location:
    Asheville, NC
    #6
    I did miss that. Changing the inequality would be another alternative, but a for loop would probably be clearer.

    The original for loop doing the string comparison is close to what it should be doing, but it has a similar bug to the new while loop, the logic is backwards (simply swap the true and false), and it still doesn't take spaces into account.
     
  7. Detrius macrumors 68000

    Joined:
    Sep 10, 2008
    Location:
    Asheville, NC
    #7
    Note that if you simplify cases and drop spaces from the reversed string, strcmp could do the rest for you.
     
  8. xStep macrumors 68000

    Joined:
    Jan 28, 2003
    Location:
    Less lost in L.A.
    #8
    Agreed. I was thinking the for loop would be easier to understand for the OP. I didn't actually analyze the inner part of the original though. As it is his exercise, he can figure out the proper coding.
     
  9. gotenks05 thread starter macrumors member

    Joined:
    Jan 1, 2009
    #9
    I looked at the manpage and it actually does what I want. The original array started at 700, in order to accommodate most strings, but it would print gibberish, if it were to be displayed, when displaying an array manually. So, strlen is used to get the real size. The only thing it does not get is the terminating null, so I'm reading your reply as needing a +1 in the actual array size. The size is set before it is used and the program goes through that prompt only once per program execution, so I don't see any problem using a variable to specify the size. I have done a somewhat similiar thing in Java and while they are different languages with different rules, that same logic should still apply.

    I'll try that. I just need to look at the ASCII table again and find out what number is a space.
     
  10. Detrius macrumors 68000

    Joined:
    Sep 10, 2008
    Location:
    Asheville, NC
    #10
    Yes. In the code posted so far, this has not been done. Everything you are doing with the value returned by strlen assumes it includes the terminating null, so you're making an array too small, and you're dropping a character off the end of the incoming string.

    I just noticed this, but you should also manually null terminate "reverse," as there's no guarantee what data is in the memory when it is allocated.

    You can simply use: ' ' That's a space character surrounded by single quotes. Double quotes makes a null-terminated char[]. Single quotes makes a char.
     
  11. gnasher729 macrumors P6

    gnasher729

    Joined:
    Nov 25, 2005
    #11
    It's C99. You can. You'll run into trouble when "size" is large. And the OP will run in trouble anyway because you need (size + 1) bytes for a string of (size) characters.
     
  12. gotenks05 thread starter macrumors member

    Joined:
    Jan 1, 2009
    #12
    Alright, thanks for the tips. I've usually been referring to the ASCII table before because that was the simplest way to target characters.
     

Share This Page