Thread: Beginner problems

  1. #1
    Registered User
    Join Date
    Oct 2012
    Posts
    126

    Beginner problems

    I'm sure you guys have people hitting you up for code and what not but I actually like to do this stuff however, I am unsure where to go from here. Thanks in advance!



    Code:
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    void errorPrint(int wrong);
    char userGuess(char guess[], int guessed);
    int getWord(char wordToGuess[], int strLength);
    
    
    int main ()
    {
    
    int wrong=1, i, n=0, guessed=0, strLength=0, j=0, r=0;
    char guess[27], wordToGuess[500], complWord[50];
    
    
    
    
    while(wrong<8 && strcmp(wordToGuess, complWord) != 0){
    
    strLength=getWord(wordToGuess, strLength);
    guessed=userGuess(guess, guessed);
    
        for(i=0;i<strLength;i++){
        
            if (wordToGuess[i]==guess[n] && i<strLength){
            complWord[i]=wordToGuess[i];
            
            printf("You got the letter %c correct!\n", wordToGuess[i]);
            n++;
            userGuess(guess, guessed);
            printf("You have %d letters left to guess!\n", (strLength-1)-n);
            
            
                continue;
              
            
        }if(i==strLength-1){
                errorPrint(wrong++);    
                userGuess(guess, guessed);
                r++;
                break;
            }    
            
        
    }
    }
    
    }
    
    
    
    
    
    
    
    char userGuess(char guess[], int guessed)
    {
    
    printf("Choose a letter you wish to guess:\n");
    scanf("%c", &guess[guessed]);
    guessed++;
    return (int)guessed;
    }
    
    
    
    
    
    int getWord(char wordToGuess[], int strLength)
    
    {
    
    FILE *fp = fopen("word.txt", "r");
    char c[1500]="/0";
    int pos = 0, n=0, k=0, len=0;
    k=rand()% ((32+1)-1)+1;
    
    
    if (fp != NULL) {
    while (fgets(c, 1500, fp) != NULL) {
    
    if (sscanf(c, "%[^,],%n", wordToGuess, &n) != 1)
    continue;
    
    printf("%s:\n", wordToGuess);
    pos += n;
    while (sscanf(c+pos, "%15[^,\n]%*c%n", wordToGuess, &n) == 1) {
    printf("\t%s\n", wordToGuess[n]);
    pos += n;
    }
    printf("\%s\n", wordToGuess);
    pos+=n;
    }
    
    }
    strLength=strlen(wordToGuess);
    fclose(fp);
    return (int)strLength;
    
    }
    
    
    
    void errorPrint(int wrong)
    {
    switch (wrong){
    case 0:
    break;
    case 1:
    printf("You have guessed %d wrong\n", wrong);
    printf(" _______\n");
    printf(" |       |\n");
    printf("         |\n");
    printf("         |\n");
    printf("         |\n");
    printf("         |\n");
    printf("_________|\n");
    break;
    
    case 2:
    printf("You have guessed %d wrong\n", wrong);
    printf(" _______\n");
    printf(" |       |\n");
    printf(" 0       |\n");
    printf("         |\n");
    printf("         |\n");
    printf("         |\n");
    printf("_________|\n");
    
    break;
    case 3:
    printf("You have guessed %d wrong\n", wrong);
    printf("  _______\n");
    printf("  |      |/\n");
    printf("  0      |\n");
    printf("|   |    |\n");
    printf("         |\n");
    printf("         |\n");
    printf("_________|\n");
    
    break;
    case 4:
    printf("You have guessed %d wrong\n", wrong);
    printf("    _______\n");
    printf("    |      |/\n");
    printf("    0      |\n");
    printf("//|   |    |\n");
    printf("           |\n");
    printf("           |\n");
    printf("___________|\n");
    
    break;
    case 5:
    printf("You have guessed %d wrong\n", wrong);
    printf("     _______\n");
    printf("    |      |\n");
    printf("    0      |\n");
    printf("//|   |\\\\  |\n");
    printf("           |\n");
    printf("           |\n");
    printf("___________|\n");
    
    break;
    case 6:
    printf("You have guessed %d wrong\n", wrong);
    printf("    _______\n");
    printf("    |       |/\n");
    printf("    0       |\n");
    printf("//|   |\\\\   |\n");
    printf("  ||        |\n");
    printf("            |\n");
    printf("____________|\n");
    
    break;
    case 7:
    printf("You have guessed %d wrong, You Lose\n", wrong);
    printf("    _______\n");
    printf("    |       |/\n");
    printf("    0       |\n");
    printf("//|   |\\\\   |\n");
    printf("  || ||     |\n");
    printf("            |\n");
    printf("____________|\n");
    
    break;
    }
    return;
    }

  2. #2
    SAMARAS std10093's Avatar
    Join Date
    Jan 2011
    Location
    Nice, France
    Posts
    2,694
    It would be nice to explain what do you want your code to do.What is the problem.What made you post? etc...

  3. #3
    Registered User
    Join Date
    Oct 2012
    Posts
    126
    the nested fors in the while loop don't work as intended, sometimes they print out multiple calls to function wordToGuess when the value is correct so first if statement. Also not sure if my function to retrieve text file string is correct. I'm supposed to get a random string from a text file and store it in the array. That stuff is new to me so not sure where exactly to go from here. And I know there's some variables in there that aren't being used. Been playing around with it a bit so have been adding/removing ideas.

  4. #4
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    EDIT: Took me a while to write all this, guess std10093 got the answer to #1 already.

    Where to go from here, or at least what to do next time you post:

    1. Give a more complete problem description. Something like: This is my hangman program, it has problem X. Problem X could be it doesn't compile, in which case you should copy-paste exact error messages with line numbers. It could be that it crashes for a given input. Tell us what that input is. It could be it gives the wrong output or behaves strangely for a given input. Tell us that input, what output you expect to get, and what you actually get.
    2. Make your code easy to read. Indent your code properly, and avoid excessive use of white space (too many blank lines in your case). If your code is formatted consistently and easy to read, it's harder to make mistakes, and easier (for you or us) to find and fix them if you do. A sample section of properly indented code is below.
    3. Compile with warnings set to the highest level, and make sure to fix all the ones you can. Again, if you can't fix some of them, give us the line number and exact error message. See below.
    4. Provide a small sample input file to help us replicate your problem if need be.


    Here is the sample of well-indented code (from your main function):
    Code:
            for (i = 0; i < strLength; i++) {
                if (wordToGuess[i] == guess[n] && i < strLength) {
                    complWord[i] = wordToGuess[i];
    
    
                    printf("You got the letter %c correct!\n", wordToGuess[i]);
                    n++;
                    userGuess(guess, guessed);
                    printf("You have %d letters left to guess!\n",
                            (strLength - 1) - n);
                    continue;
                }
                if (i == strLength - 1) {
                    errorPrint(wrong++);
                    userGuess(guess, guessed);
                    r++;
                    break;
                }
            }
    Warnings I get when compiling your code (note, the line numbers don't match, I had to fix your formatting before I bothered with anything else).
    Code:
    $ make hangman
    gcc -g -Wall -std=c99 -o hangman hangman.c -lpthread -lm -lpq
    hangman.c: In function ‘main’:
    hangman.c:11:58: warning: unused variable ‘j’ [-Wunused-variable]
    hangman.c: In function ‘getWord’:
    hangman.c:64:17: warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘int’ [-Wformat]
    hangman.c:52:32: warning: unused variable ‘len’ [-Wunused-variable]
    hangman.c:52:25: warning: variable ‘k’ set but not used [-Wunused-but-set-variable]
    Line 64 is definitely a problem, it could cause a crash. The rest are trivial, but should be fixed regardless.

    Some other things I noticed (this was a quick 5-minute overview, so I probably missed plenty:

    • Use some comment to explain the less obvious stuff, like what you are doing with the variable k in getWord().
    • Way too many "magic numbers". #define some constants, it will help you avoid array overflows, especially if you change any array sizes.
    • userGuess returns a char, but you cast the return value to an int (but it's already an int). This function should probably return an int.
    • In getWord, you initialize c incorrectly. You are initializing it to a string with 2 characters, the '/' and the '0'. If you want the null terminator, it's a backslash, '\0'. But you could just do char c[MAX_LINE] = ""; with nothing between the double quotes. That makes an empty string, i.e. the first character is a null character.
    • You may find the strtok function to be of use inside the while loop in getWord, instead of your scanf stuff.
    • In general, follow a good development process. First, understand the problem to be solved. Then, come up with a solution on paper in your native language. Turn that into pseudo code, and test your pseudo code with paper and pencil. Then, turn that pseudo code into real code. Only write 5-10 lines of code at a time. Stop, compile (with strict warnings), and fix them all. Then test those 5-10 lines and make sure they behave the way you expect. Move on to the next 5-10 lines, continue until you're done.

  5. #5
    Registered User
    Join Date
    Oct 2012
    Posts
    126
    I think my lines are different than yours I'm pretty sure it's for using an int as a pointer reference in a printf statement, and I just put it there to check the value originally. What I need to do is get the main function to stop repeating in the if(wordToGuess[i] side of the problem. Also I need to set my string that is random to the array. Would I just do say something like

    Code:
    
    n=rand()% ((31+1)-1)+1;
    fgets(buffer,500,fp);
    if (fp){
    for(i=0;i<n;i++){
    fscanf(fp, "%s", wordToGuess);
    }

  6. #6
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    How thoroughly did you read my post? I know it's quite long. I told you the line numbers wont match. Also, I told you to work this out on paper. You shouldn't be writing code until you are 100% certain you have the right logic and solution. Write out the steps in plain English, and work through some examples before you code anything.

    Your solution is probably sort of right, except ((31+1)-1) should just be 31. But even that is not very correct. WTF is 31 anyway? Why not 32 or 42 or 517? No magic numbers. Count how many words in the file, or #define it as a constant if it will never change values.

    You didn't say what the input file looks like, so I'm assuming, for the purpose of this example, it's one word per line. Try something like:
    Code:
    open the file for reading
    count how many lines (words) in the file, call this numWords
    generate a random number between 1 and numWords, inclusive, call this random number n
    go back to the beginning of the file
    read one line(word) at a time from the file until you reach the nth word
    copy that word into the wordToGuess char array
    close the file
    That is where you should start, for every piece of this program, in simple English. Then translate this to pseudo code. Don't sweat syntax or anything yet, but something with a more programming structure, like:
    Code:
    open the file for reading
    if opening fails
        print an error
        return from the function with an error code or exit the program
    
    numWords = 0
    while fgets(buffer, ...) != NULL
        numWords++
    
    k = random number from 1 to numWords
    rewind file to beginning
    
    for i from 1 to k
        read a line into buffer
    
    read one more line into buffer
    strcpy(line, buffer)
    close the file
    Again, that's pseudo code, and I didn't test it, so there may be errors in my logic. You also need to test the actual code you write for this as you go.

  7. #7
    Registered User
    Join Date
    Oct 2012
    Posts
    126
    Quote Originally Posted by anduril462 View Post
    How thoroughly did you read my post? I know it's quite long. I told you the line numbers wont match. Also, I told you to work this out on paper. You shouldn't be writing code until you are 100% certain you have the right logic and solution. Write out the steps in plain English, and work through some examples before you code anything.

    Your solution is probably sort of right, except ((31+1)-1) should just be 31. But even that is not very correct. WTF is 31 anyway? Why not 32 or 42 or 517? No magic numbers. Count how many words in the file, or #define it as a constant if it will never change values.

    You didn't say what the input file looks like, so I'm assuming, for the purpose of this example, it's one word per line. Try something like:
    Code:
    open the file for reading
    count how many lines (words) in the file, call this numWords
    generate a random number between 1 and numWords, inclusive, call this random number n
    go back to the beginning of the file
    read one line(word) at a time from the file until you reach the nth word
    copy that word into the wordToGuess char array
    close the file
    That is where you should start, for every piece of this program, in simple English. Then translate this to pseudo code. Don't sweat syntax or anything yet, but something with a more programming structure, like:
    Code:
    open the file for reading
    if opening fails
        print an error
        return from the function with an error code or exit the program
    
    numWords = 0
    while fgets(buffer, ...) != NULL
        numWords++
    
    k = random number from 1 to numWords
    rewind file to beginning
    
    for i from 1 to k
        read a line into buffer
    
    read one more line into buffer
    strcpy(line, buffer)
    close the file
    Again, that's pseudo code, and I didn't test it, so there may be errors in my logic. You also need to test the actual code you write for this as you go.
    Yeah that's just the logic to the max min values of the random function if you want to have a decent shot at getting a different number without having to go off clock cycles. I usually build it in sections, start small work my way up. But as I am still learning I try and code as I go if I already have a structure going to try and troubleshoot myself. However I know the logic I want for the int main loop just isn't coming to me how to do it better. I read what you said, I understand I need to work on how I structure my programs. Most of the time if I'm online I'm just reading, looking at examples and then I just try something on my own. If it doesn't work in the function, I try something else. I usually have 6-7 notepad ++ windows open, which is probably why my formatting needs work. I will try and get better at that

  8. #8
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Okay, for your main loop, you have something like this:
    Code:
    display all the letters the user has guessed so far
    have the user guess a letter
    if that letter is in the word, reveal all occurances of it
        if they have revealed the whole word, print "you win" and exit
    otherwise, increment the "wrongGuess" counter and display the "hangman"
        if they have too many wrong guesses, print "you lose", and exit
    otherwise go back to the top
    I would make sure to have the following 3 arrays (I think you have at least two of these):

    1. The wordToGuess array
    2. A version of the word to print out, where you can only copy in the letters they have correctly guessed. This should start out as a string the same length as wordToGuess, but all spaces (or underscores, dashes, dots, asterisks, whatever so the user knows how many letters total).
    3. An array to keep track of what letters the user has guessed, so they don't guess the same one twice. Print this every time you ask them: "Here are the letters you guessed so far, pick a new letter".



    When you're done implementing all the suggestions so far, post back with your updated code and we'll go from there.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Beginner Programming Problems
    By shukiren in forum C Programming
    Replies: 3
    Last Post: 09-25-2011, 01:44 AM
  2. Array Problems? (Im a beginner)
    By scarlet00014 in forum C Programming
    Replies: 8
    Last Post: 09-19-2008, 02:59 PM
  3. beginner function problems
    By mngt in forum C Programming
    Replies: 15
    Last Post: 02-28-2008, 12:35 AM
  4. beginner problems with array elements...
    By grnphrog in forum C Programming
    Replies: 4
    Last Post: 01-27-2003, 02:38 PM
  5. problems as a beginner 1
    By Moffesto in forum C++ Programming
    Replies: 4
    Last Post: 06-21-2002, 11:16 PM