Thread: Global variable going bonkers

  1. #1
    Registered User Alpo's Avatar
    Join Date
    Apr 2014
    Posts
    877

    Global variable going bonkers

    Hello all, I've been putting together this game of hangman from bits and pieces of other programs I've wrote while learning C. It's not done, but I'm building it slowly so I can check the pieces for efficacy in the building process.

    My concern is with the global variable called "wrongguess" (Ironic), the function called verify() is meant to increment wrongguess whenever a pattern match is not found. Instead of adding 1, it immediately jumps to 40 or so, then jumps again to it's max int type size. This is a problem because the while loop in main is currently using wrongguess's value to determine the number of guesses player 2 has left to make.

    Code:
    #include<stdio.h>
    #define ARRSIZE 50
    #define SCREENSIZE 25
    int wrongguess=0;
    
    void verify(char arr2[], char arr[], char guess[]);
    
    void low(char arr2[], char arr[]);
    
    void clrscrn(void);
    
    main()
    {
        char arr[ARRSIZE];
        char guess[ARRSIZE];
        char arr2[ARRSIZE]={'_',.../**ect**/...,'_'};
    
        printf("Enter Phrase:");
        fgets(arr, ARRSIZE, stdin);
        clrscrn(); /**Generate newlines**/
    
        while(wrongguess<7){    /**>>variable value check here<<**/
            printf("\nIncorrect guesses #%-3d\nPlayer 2 guess:");
            fgets(guess, ARRSIZE, stdin);
            verify(arr2, arr, guess);
            printf("\n%s", arr2);
        }
        return 0;
    }
    
    
    void verify(char to[],char from[], char guess[])
    {
        int copy, check, j, k;
        extern int wrongguess;
        low(to, from);
    
        /**Cleaning the newlines**/
        for (copy=0; from[copy]!='\0'; ++copy){
            if (from[copy]=='\n'){
                from[copy]='\0';
                to[copy]='\0';
            }
            if(guess[copy]=='\n'){
                guess[copy]='\0';
            }
        }
    
        for(check=0; check<ARRSIZE; check++){
            for(j=check, k=0; guess[k]!='\0'&& from[j]!='\0'; ++j,++k){
                /**For loop pattern check here**/
                if (from[j]==guess[k]){
                    /**copy if correct**/
                    to[j]=guess[k];
                }
    
                    /**if not matching ++wrongguess, BROKE**/
                else if (from[j]!=guess[k]){
                    ++wrongguess;
                    break;
                }
            } 
    
                /**punctuation copy**/
            if(from[check]==' ' || from[check]=='.' || from[check]=='?' ||  from[check]=='"' || from[check]==','){
                to[check]=from[check];
            }
        }
    }
    
    void low(char to[], char from[])
    {
        int scan;
        /**This only works with ascii, but the tolower function
        was having some interaction with the verify function, and
        not copying capital letters put arbitrarily at the beginning
        of words.**/
        for (scan=0; scan<ARRSIZE; ++scan){
            if (to[scan]>='A' && to[scan]<='Z')
                to[scan]+=32;
            if (from[scan]>='A' && from[scan]<='Z')
                from[scan]+=32;
        }
    }
    void clrscrn(void)
    {
        /**This might be better off not as a function, but I didn't
        want the for loop dirtying up the main function**/
        int i;
        for (i=0; i<=SCREENSIZE; ++i){
            putchar('\n');
        }
    }
    Any help appreciated, and thanks.
    Last edited by Alpo; 04-19-2014 at 03:01 PM. Reason: Comment for newline cleaner.

  2. #2
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    Instead of adding 1, it immediately jumps to 40 or so, then jumps again to it's max int type size.
    O_o

    What exactly makes you think that?

    Hint: Be very specific...

    Soma
    “Salem Was Wrong!” -- Pedant Necromancer
    “Four isn't random!” -- Gibbering Mouther

  3. #3
    Registered User
    Join Date
    Mar 2012
    Location
    the c - side
    Posts
    373
    Well you're missing a variable here:

    Code:
      printf("\nIncorrect guesses #%-3d\nPlayer 2 guess:");
    Might be a matter of taste, but for readabilty I would say you've put too much into a single line, and it would be much better to split it into two lines of code.
    If you don't have a newline character at the end of the printf() string, you should also use fflush(stdout) immediately following.
    Also you must be missing a header for clrscrn().

    Edit: just noticed clrscrn() is your own function so forget that.
    Last edited by gemera; 04-19-2014 at 04:10 PM.

  4. #4
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    It would be useful if you provided ACTUAL code, rather than a mess that won't compile.

    The symptom you describe is a classic indicator of a buffer overrrun .... accessing more elements of an array than it has.

    Check your loops. Step through with a debugger.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  5. #5
    Registered User Alpo's Avatar
    Join Date
    Apr 2014
    Posts
    877
    @ Grumpy, it was missing a variable on a printf like gemera said, which was a simple mistake from editing. I'm getting no warnings or errors with it inserted back. I will check the for loops and conditions, but up until the inclusion of wrongguess everything in the program until that point was working as expected, I'm fairly sure the arrays weren't overflowing.

    @ Phantomotap- I was wrong, It doesn't go to max int size, with the variable back in the printf the value wrongguess jumps by is 36 consistently.

    Here is the full code, I was just trying to keep it from running off the screens edge with all the underscores.

    Code:
    #include<stdio.h>
    #define ARRSIZE 50
    #define SCREENSIZE 25
    int wrongguess=0;
    void verify(char arr2[], char arr[], char guess[]);
    void low(char arr2[], char arr[]);
    void clrscrn(void);
    main()
    {
        char arr[ARRSIZE];
        char guess[ARRSIZE];
        char arr2[ARRSIZE]={'_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_'};
        printf("Enter Phrase:");
        fgets(arr, ARRSIZE, stdin);
        clrscrn(); /**Generate newlines**/
        while(wrongguess<10000000){ /**>>variable value check here, added a huge value so you could see wrongguess jumping up.<<**/
            printf("\nIncorrect guesses #%-3d\nPlayer 2 guess:", wrongguess);  /**Wrongguess printed here, thanks gemer........../
            fgets(guess, ARRSIZE, stdin);
            verify(arr2, arr, guess);
            printf("\n%s", arr2);
        }
        return 0;
    }
    void verify(char to[],char from[], char guess[])
    {
        int copy, check, j, k;
        extern int wrongguess;
    
        low(to, from);
                    /**This part replaces newline with null**/
        for (copy=0; from[copy]!='\0'; ++copy){
            if (from[copy]=='\n'){
                from[copy]='\0';
                to[copy]='\0';
            }
            if(guess[copy]=='\n'){
                guess[copy]='\0';
            }
        }
        for(check=0; check<ARRSIZE; check++){
            for(j=check, k=0; guess[k]!='\0'&& from[j]!='\0'; ++j,++k){
                /**For loop pattern check here**/
                if (from[j]==guess[k]){
                    /**copy if correct, slight bug with lining
                    up addresses of from & guess, can't fix without
                     rearranging guess**/
                    to[j]=guess[k];
                }
                    /**if not matching, add 1 to wrongguess-broken**/
                else if (from[j]!=guess[k]){
                    ++wrongguess;
                    break;
                }
            }
                /**punctuation copy**/
            if(from[check]==' ' || from[check]=='.' || from[check]=='?' || from[check]=='"' || from[check]==','){
                to[check]=from[check];
            }
        }
    }
    
    void low(char to[], char from[])
    {
        int scan;
        /**This only works with ascii, but the tolower function
        was having some interaction with the verify function, and
        not copying capital letters put arbitrarily at the beginning
        of words.**/
        for (scan=0; scan<ARRSIZE; ++scan){
            if (to[scan]>='A' && to[scan]<='Z')
                to[scan]+=32;
            if (from[scan]>='A' && from[scan]<='Z')
                from[scan]+=32;
        }
    }
    void clrscrn(void)
    {
        /**This might be better off not as a function, but I didn't
        want the for loop dirtying up the main function**/
        int i;
        for (i=0; i<=SCREENSIZE; ++i){
            putchar('\n');
        }
    }
    Last edited by Alpo; 04-19-2014 at 05:00 PM. Reason: Full code,

  6. #6
    Registered User Alpo's Avatar
    Join Date
    Apr 2014
    Posts
    877
    Ok, perhaps the reason it wouldn't compile on others computers is because certain characters seem to be changing when I post the code. I'm not sure what I can do about that, I've tried manually editing it several times now. The line /**wrongguess printed here, thanks gemer........../ is showing on my screen as /**Wrongguess printed here, thanks gemer........../.

    Sorry about that.

  7. #7
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    Grumpy, it was missing a variable on a printf like gemera said, which was a simple mistake from editing.
    O_o

    Yes. However, that isn't your real problem; that is a "red herring".

    I was wrong, It doesn't go to max int size, with the variable back in the printf the value wrongguess jumps by is 36 consistently.
    No. It does not "[jump] by is 36 consistently". The relationship, the value being "jumped" isn't even important.

    Consider where/how the value being "jumped" is made.

    If you can't follow then as grumpy advised, step through the code with a debugger.

    Ok, perhaps the reason it wouldn't compile on others computers is because certain characters seem to be changing when I post the code.
    1): Remove the comments.
    2): Learn to use `memset'.
    3): Learn to use `tolower'.

    Soma
    “Salem Was Wrong!” -- Pedant Necromancer
    “Four isn't random!” -- Gibbering Mouther

  8. #8
    Registered User
    Join Date
    Mar 2012
    Location
    the c - side
    Posts
    373
    You should be able to break that one massive line into several shorter ones. Say 5 lines of 10 of '_' each or so simply by pressing return after the comma. Works in Codeblocks with mingw anyway.

    Edit: but probably better to just write your own function to initialise the array.
    Last edited by gemera; 04-19-2014 at 05:19 PM.

  9. #9
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Alpo: some general advice.

    First, read this link on asking questions in a manner more likely to elicit a useful response.

    Second, if you don't apply effort needed to actually framing your question and presenting workable code in a coherent manner (the problem is a shotgun approach, not deficiencies of browsers or site software) you can't be surprised if folks seem unwilling to apply much effort to help.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  10. #10
    Registered User
    Join Date
    Mar 2012
    Location
    the c - side
    Posts
    373
    Quote Originally Posted by phantomotap View Post
    O_o

    Yes. However, that isn't your real problem; that is a "red herring".
    And the plot thickens..............

  11. #11
    Registered User Alpo's Avatar
    Join Date
    Apr 2014
    Posts
    877
    @ Grumpy- I read a very similar thing in laserlights sig tag, I try to read everything. I am trying to apply the effort.

    @ Phantomotap- I will try to figure everything out, but it will take time. Thank you for the hints, I'll post back when I get some debugger info.

  12. #12
    Registered User Alpo's Avatar
    Join Date
    Apr 2014
    Posts
    877
    Ok, I'm back from the Codeblocks debug wiki, and I ran the debugger and got some info. I moved wrongguess from the verify function, into a function specifically made for it. I added breakpoints and stepped through the thing several times, watching the variables.

    From the beginning the new function behaved differently, I did not declare wrongguess an extern in this function. I still am not sure about the red herring, unless it was that I had wrongguess declared as an extern when it wasn't needed.

    It seems to be incrementing normally now, the debugger isn't reporting anything alarming that I understand the meaning of. At one point while trying out different if statements that control the increment of wrongguess, I made a mistake (putting a !=, when I meant to put ==), and wrongguess went up in proportion to the for loop that is controlling it. It was all very interesting, and I will definitely use the debugger from now on.

    @phantomotap- I just thought I'd add about tolower, I started out using it on this, but it wasn't acting right in the verify function. It was all in the comments. I've read about memset, but didn't think of it, thank you.
    Last edited by Alpo; 04-19-2014 at 07:48 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. static global variable and static extern global variable
    By gunjansethi in forum C Programming
    Replies: 8
    Last Post: 01-12-2011, 01:00 AM
  2. Replies: 8
    Last Post: 09-27-2010, 04:11 PM
  3. Static Local Variable vs. Global Variable
    By arpsmack in forum C Programming
    Replies: 7
    Last Post: 08-21-2008, 03:35 AM
  4. static class variable vs. global variable
    By nadamson6 in forum C++ Programming
    Replies: 18
    Last Post: 09-30-2005, 03:31 PM
  5. Static global variable acting as global variable?
    By Visu in forum C Programming
    Replies: 2
    Last Post: 07-20-2004, 08:46 AM

Tags for this Thread