Thread: New to C, need debugging help

  1. #1
    Registered User
    Join Date
    Feb 2011
    Posts
    9

    New to C, need debugging help

    Introduction:
    Before I get started, this is an advance warning that I've never coded in C before. I've taken 2 years of java-related programming, but C is a brand new animal for me. This is for a class I'm currently taking, so I'd appreciate knowing the more basic ways of solving these problems rather than using new files or advanced work-around. That's how we learn, right?

    Relavent information:
    • I am using C-Free 5.0, and coding by C99 standards.
    • There is one file read, which contains:
      Code:
      12 196 295 394 493 592 689 788 790 879 877 978 986
      It is located at the root directory of the .c file.
    • I will update the provided code of my file/provided list as they change, and will ask a new question each time I do so until it's working. Please check the most recent questions, as previous ones may not apply to the new code.


    The Program:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <stdbool.h>
    int i;//Counter
    
    /**
    *	Author Comments
    *	Variables are defined throughout various functions or bracketed sections when they apply
    *	only to that section.
    *
    */
    
    /**
    *	Function to reverse the order of a provided number.
    *	Returns reversed number
    */
    int reverseOrder(int number1)
    {
    	int reversedNumber;
    	char forwardsBuffer[32];
    	int length;
    	char backwardsBuffer[32];
    	int counter1 = 0;//Counter for backwardsBuffer
    	
    	itoa(number1,forwardsBuffer,10);
    	for (i=strlen(forwardsBuffer)-1; i--; i <=0)
    	{
    		backwardsBuffer[counter1] = forwardsBuffer[i];
    		counter1++;
    	}
    	itoa(reversedNumber,backwardsBuffer,10);
    	return reversedNumber;
    }
    
    /**
    *	Checks a number to see if it is a palendrome.  Returns bool.
    */
    bool checkPalendrome(int number2)
    {
    	int first, last;
    	bool returnValue = false;//One digit palendrome
    	if (reverseOrder(number2) == number2)//3+ digit palendrome
    		{
    			returnValue = true;
    		}
    	return returnValue;
    }
    
    /**
    *	Handles palendrome/reverse addition and itteration count
    */
    int palendromeAddition(int number3)
    {
    	int itterationCounter = 0;
    	int reversedNumber;
    	int summation;
    	while (checkPalendrome(number3) != true)
    	{
    		reversedNumber = reverseOrder(number3);
    		summation = number3 + reversedNumber;
    		printf("%19d + %19d = %20d\n", number3, reversedNumber, summation);
    		number3 = summation; // Repeats with new sum.
    		itterationCounter++;
    	}
    	printf("A palendrome was obtained in %d itterations.\n\n", itterationCounter);
    }
    
    int main()
    {
    	
    	int sizeOfLychrelList;
    	char fileName[256];
    	char nextLychrelChar[16];
    	char sizeOfLychrelListChar[16];
    	int n = 1; //Initial number to work with.  Initializes as a nonzero.
    	
    	printf("Please input the candidate lychrel filename: ");
    	gets(fileName);
    	
    	FILE *lychrelFile;
    	if ((lychrelFile=fopen(fileName, "r")) == NULL) { //opens the file
        	printf ("Error opening file\n");
        	exit (-1);
    	}
    	fgets(sizeOfLychrelListChar, 10, lychrelFile);//Gets the first number of the file and stores it as the number of lychrels
    	sizeOfLychrelList = atoi(sizeOfLychrelListChar);
    	int lychrels[sizeOfLychrelList];//Array that stores the lychrels
    	
    	/**
    	* Generates an int list of all lychrels found within the file.
    	*
    	*/
    	for(i=0; i++; i<sizeOfLychrelList)
    	{
    		fgets(nextLychrelChar,20,lychrelFile);
    		lychrels[i] = atoi(nextLychrelChar);
    	}
    	i = 0;//Resets i for reuse later
    	printf("Please input the value of N: ");
    	scanf("%d", n);
    	
    		
    	while(n != 0)// Entry of 0 will quit the program
    	{
    		while (n > lychrels[i] && n != lychrels[i] && i < sizeOfLychrelList)//Ensures that n is not a candidate lychrel
    		{
    			i++;
    		}
    		if (n == lychrels[i])//Checks if n is a Lychrel Candidate
    		{
    			printf("%d is a Candidate Lychrel.\n", n);
    		}
    		else if (i > sizeOfLychrelList)//Ensures that n is less than the maximum Lychrel Candidate supplied; otherwise n could be an unlisted lychrel and cause a crash.
    		{
    			printf("Supplied lychrel list limits exceeded, cannot process with certainty");
    		}
    		else if (checkPalendrome(n))
    		{
    			printf("%d is a palendrome.", n);
    		}
    		else
    		{
    			palendromeAddition(n);
    		}
    		printf("Please input the value of N: ");
    		scanf("%d", n);	
    		i = 0;	
    	}
    	printf ("\nGoodbye\n");
       	exit (-1);
    }
    Problems:
    Problem 1: Syntactically my program works, but it likes to break at line 63:
    Code:
    summation = number3 + reversedNumber;
    The error message is "Program stopped at 0x7539ecc0. It stopped with signal SIGSEGV, segmentation fault." Initially I had some run-ins with "segmentation faults" when setting up the reading process for the attached test file. I assume it has something to do with this?

  2. #2
    Registered User
    Join Date
    Feb 2011
    Posts
    9
    Thought it might be a problem with datatype size (are ints in C really THAT much smaller than in Java? Wow.) so I changed every reference to numbers used for calculation, return types, and basically all non-counter/size ints, to the datatype "long long" as suggested by my professor.

    No dice, same problem.

  3. #3
    Registered User
    Join Date
    Feb 2011
    Posts
    9
    hate to do it, but bump over the wall of spam.

  4. #4
    -bleh-
    Join Date
    Aug 2010
    Location
    somewhere in this universe
    Posts
    463
    The palidomeaddition unction needs to return something.
    Last edited by nimitzhunter; 02-15-2011 at 10:55 PM.
    "All that we see or seem
    Is but a dream within a dream." - Poe

  5. #5
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    Welcome to the forum, Theta Zero!

    Your compiler will have a macro to tell you it's range for any data type. Mine is in the <limits.h> file, but yours may be in another header file. INT_MAX, is one of them. (oddly, I have two of these macro's for each data type, in two different header files. For compatibility I'm sure).

    In all cases, in any language, data types are limited in range to the size they occupy in total bits (for all bytes included in that data type), since the computer works with binary data, only.

    Just before your "problem 1" line of code, look at the two numbers, and see if, when added together, they are greater than your max (or min if negative), data range. That will get you looking for bugs, in the right area, at least.

    The more specific you can be about describing your problem, the better our advice will be. If your compiler warnings are not turned up all the way, please do that.

  6. #6
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,218
    I've never seen C crash on a simple addition or assignment involving integers unless the stack is getting corrupted somehow.

    There are several things wrong with your program, and a few things that are common beginner no-no's:

    1) for(i=0; i++; i<sizeOfLychrelList)

    You do this in other places too. I'm pretty sure for() loops in Java are structured the same way as in C, but the condition goes in the middle section: for(i = 0;i < sizeOfLychrelList;i++)

    2) gets(filename)

    gets() is evil and should never be used.

    3) exit(-1)

    Only the least 8 significant bits get returned to the caller, so the negative bit is getting stripped away anyway, effectively passing the same as 1 to the caller. Something to watch out for:
    "The value of status may be 0, EXIT_SUCCESS, EXIT_FAILURE, or any other value, though only the least significant 8 bits (that is, status & 0377) shall be available to a waiting parent process."

    4) fgets(nextLychrelChar,20,lychrelFile);

    You're reading up to 20 chars, but nextLychrelChar is only declared to contain 16 elements. This could cause a buffer overflow.

    5) scanf("%d", n);

    You need to pass the address of n to to scanf() so it knows where to store the input: scanf("%d", &n);

    6) palendrome

    It's spelled 'palindrome'.

    That's all for now. I haven't tried running the program to see what would happen for me. I will say that I've never heard of that compiler before. However, if your compiler has warnings, I would turn them on and read them. It should have told you about some of those problems.
    Last edited by itsme86; 02-15-2011 at 11:10 PM.
    If you understand what you're doing, you're not learning anything.

  7. #7
    Registered User
    Join Date
    Feb 2011
    Posts
    9
    Debugging manually lead me to question this:
    Code:
    printf("Please input the value of N: ");
    scanf("%d", n);
    printf(n);
    Commenting out all the rest of the code (except functions) after causes it to crash at the same point; right after inputting N.

    EDIT: In the process of fixing the above
    Last edited by Theta Zero; 02-15-2011 at 11:30 PM.

  8. #8
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    That takes care of #5 in Itsme's list.

  9. #9
    Registered User
    Join Date
    Feb 2011
    Posts
    9
    That &n fixed 90% of my problems. I also fixed the rest of the issues for good programming form, although admittedly my for loops were due to poor note-taking. All that's left is to sort out my storing the given file to the proper array, and that I can handle myself. Thank you very much for all the assistance!

  10. #10
    Registered User
    Join Date
    Feb 2011
    Posts
    9
    Ok, I can't figure this out for the life of me.

    Code:
    for (i = 0; i < sizeOfLychrelList; i++)
    {
    	if (lychrels[i] == n)
    	{
    		isLychrel = true;
    	}
    }
    if (isLychrel == true)
    {
    	printf("%d is a Candidate Lychrel.\n", n);
    }
    Lychrels[i] appears to be an array full of 0's, so it never detects a lychrel. However, if I run a print loop just before the while statement, it shows lychrels[] as being full and containing the correct data. What's causing my data to vanish?

    EDIT: Having a for loop to display Lychrels[] after the for loop in the above example, before the boolean check, shows Lychrels to still contain the correct data. It's only gone in the second, nested for loop.
    Last edited by Theta Zero; 02-16-2011 at 08:22 PM.

  11. #11
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    I hope you adopt a sane way to indent your code. That is just miserable.

    Code:
    for (i = 0; i < sizeOfLychrelList; i++)
    	{
    		if (lychrels[i] == n)
    		{
    			isLychrel = true;
    		}
    	}
    	if (isLychrel == true)
    	{
    		printf("%d is a Candidate Lychrel.\n", n);
    	}
    In the bolded code, did you mean 'n'?

  12. #12
    Registered User
    Join Date
    Feb 2011
    Posts
    9
    I apologize, my IDE and copy/paste like to fight with eachother.

    n is an input number rather than a character, obtained with
    Code:
    scanf("%d", &n);
    lychrels[] is an array of long longs.

  13. #13
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    OK, you have the two if statements. It's not apparent by looking at them, but they are sequential. So what happens when isLychrel is TRUE, one time? (and should true be TRUE, instead of true?)

    I don't see it ever being reset to FALSE.

    Set your IDE up to replace tabs with N number of spaces, instead. Under editor options.

    Or slip me a grenade. Truly, I hate that ungodly style of non-formatting.
    Last edited by Adak; 02-16-2011 at 08:37 PM.

  14. #14
    Registered User
    Join Date
    Feb 2011
    Posts
    9
    larger excerpt of my current code below:
    Code:
    printf("Please input the value of N: ");
    scanf("%d", &n);
    while(n != 0)// Entry of 0 will quit the program
    {
       for (i = 0; i < sizeOfLychrelList; i++)
       {
          if (n == lychrels[i])
             isLychrel = true;
       }
       if (isLychrel == true)
          printf("%d is a Candidate Lychrel.\n", n);
       if (isLychrel == false && checkPalindrome(n))
          printf("%d is a palendrome.\n", n);
       if (isLychrel == false && (checkPalindrome(n) != true))
          palindromeAddition(n);	
       printf("Please input the value of N: ");
       scanf("%d", &n);
       isLychrel = false;
    }
    printf ("\nGoodbye\n");
    exit (1);
    isLychrel (type bool) is never instantiating to "true" on any of the passes, even if the number is contained in the list. Lychrel[0] is 196, but entering 196 as n still tries to go through the entire process rather than immediately changing isLychrel to true and then skipping the latter two if statements.

    EDIT: Sorry about the formatting, I'm working on it.
    Last edited by Theta Zero; 02-16-2011 at 09:02 PM.

  15. #15
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    The only thing you can do is step through the code, and watch your n, lychrel[i] and sizeOfLychrelList, and i variables.

    It looks right, but if it's not working, there's a problem with one of these suspects, I expect.

    If you want one if statement to exclude the other two, make the other two else if statements, to the if().

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. help debugging in Pelles C IDE
    By gaurav9991 in forum C Programming
    Replies: 3
    Last Post: 10-30-2010, 07:15 AM
  2. Replies: 13
    Last Post: 08-12-2010, 01:58 PM
  3. Dev-C++: Problems with Breakpoint Debugging
    By Thileepan_Bala in forum C Programming
    Replies: 1
    Last Post: 01-17-2008, 10:48 AM
  4. Debugging book recommendation
    By dagans in forum Projects and Job Recruitment
    Replies: 1
    Last Post: 09-13-2005, 07:35 PM
  5. debugging directx apps
    By confuted in forum C++ Programming
    Replies: 1
    Last Post: 08-16-2003, 08:56 AM