Thread: Problems with strings and for loops

  1. #31
    Registered User
    Join Date
    Dec 2003
    Posts
    53
    forget about returning a value from checkchar, and pass a pointer to correctguess to the function instead, in order to increment the counter. Doing this will also allow you to compare correctguess to wordlength without any adjustments - I was mistaken before when I said that the 'e' guess would make correctguess a couple less than wordlength.
    One possible problem with this method is that what happens if the user decides to enter 'e' twice for the sake of it?

    number of 'e's in cheese == 3;
    first run through checkchar with 'e',
    correctguess == 3;
    second run through checkchar with 'e',
    function still checks and finds 3 'e's in the word2bguessed,
    as a result,
    correctguess == 6 (which also means correctguess == wordlength)


    Here is an alternative method, return the number of '*'s in the usercorrect string...
    Assuming you initialize the number of '*'s in the usercorrect to == the number of characters in the word2bguessed, the number of '*'s in the usercorrect will be equal to the number of characters that the user has yet to guess correctly.
    Last edited by tzuchan; 03-31-2004 at 08:59 PM.

  2. #32
    Been here, done that.
    Join Date
    May 2003
    Posts
    1,164
    Quote Originally Posted by petedee
    Its ok, i seem to have fixed it, i still used scanf but i changed "%s" to " %c" it seems to have done the trick...
    FYI,
    Code:
    ch = getchar();
    will do exactly what
    Code:
    scanf("%c", &ch);
    does, only faster and neater. scanf() does so much work analyzing your format string then reading the keyboard that for a char it's just not worth it.

    Also, as you start using more comples input, you'll find scanf() causes more problems than it solves. You'd be better off using the simple I/O function and leave scanf() behind.
    Definition: Politics -- Latin, from
    poly meaning many and
    tics meaning blood sucking parasites
    -- Tom Smothers

  3. #33
    Registered User
    Join Date
    Jan 2004
    Posts
    50
    Here is an alternative method, return the number of '*'s in the usercorrect string...
    Assuming you initialize the number of '*'s in the usercorrect to == the number of characters in the word2bguessed, the number of '*'s in the usercorrect will be equal to the number of characters that the user has yet to guess correctly.
    So rather than count correct letters count the ones the blanks that are left? would i be better off putting that in a new function?

  4. #34
    Registered User
    Join Date
    Dec 2003
    Posts
    53
    Quote Originally Posted by petedee
    So rather than count correct letters count the ones the blanks that are left? would i be better off putting that in a new function?
    Essentially yes. Regarding whether to put that into another function is entirely up to you, although you should note that it may be easier to keep track of bugs if you create another function.

  5. #35
    Registered User
    Join Date
    Jan 2004
    Posts
    50
    Its all fixed! Thanks for you help guys, doubt i could have ever done this without your help
    Last edited by petedee; 04-01-2004 at 07:14 AM.

  6. #36
    Registered User
    Join Date
    Jan 2004
    Posts
    50
    Damn bugs! one more then i swear thats it!

    Ok so I'm checking to code to see if the same letter has being guessed more than once, I'm guessing i'll need to pass the function the letters which are being guessed and generate an array of characters which are the ones that have being stored; here is what i have so far

    decleration:

    Code:
    void prelets (char let2bg);
    function call:
    Code:
    prelets (let2bg);
    function code:
    Code:
    void prelets (char let2bg)
    	{
    	int k;
    	for (k=0; usedlets[k] != '\0'; k++)
    		if (let2bg == usedlets[k])
    			{	
    			printf ("already used)");
    			printf ("%s",usedlets);
    			}
    		
    		return usedlets;
    	}
    I know i have to make an array for usedlets but whenever i do it always asks me the size i want it to be, i don't know this because i don't know how many right guesses and wrong guesses the user will input.

    Rest of the code is here: http://rafb.net/paste/results/I1638768.html

  7. #37
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >i don't know this because i don't know how many right guesses and wrong guesses the user will input.
    This is a classic problem for programmers. Do you go with the simple solution and restrict the size to some arbitrary value? Or do you create a data structure that can resize itself dynamically? My recommendation is to set a maximum size and use a simple array to get your program working. Then you can add features to it, such as a dynamic array or a linked list.
    My best code is written with the delete key.

  8. #38
    Registered User
    Join Date
    Dec 2003
    Posts
    53
    Quote Originally Posted by petedee
    I know i have to make an array for usedlets but whenever i do it always asks me the size i want it to be, i don't know this because i don't know how many right guesses and wrong guesses the user will input.
    Disregarding the fact that there's no array, your code for the most part looks workable(I won't say good... yet) but for the point where you want to print out the whole array of characters that the user has entered.

    In anycase, one point to note about how big the array should be. How many guesses can the user make? if that's the limiting factor for gameover, which it is since the user can enter at the most maxnumberofguesses, a array of maxnumberofguesses would be sufficient to hold how many different letters he's entered.

  9. #39
    Registered User
    Join Date
    Jan 2004
    Posts
    50
    I've being racking this over in my head and i just can't see any way to do it, i thought about using an if statement to check it something along the lines of:

    Code:
    	for (k = 0; usedchars [k] != '\0'; k++)
    	
    	{
    		if (let2bg = usedchars[k])
    		{
    		printf ("old");
    		printf ("%s", usedchars);
    		}
    	else
    		{k++;
    its a messy way of doing things and it never seems to do anything, I'm just really stuck on the way i should do this? Do i need a for loop? should it be in a function? if so what needs to be returned? How do i stop it printing a load of gibberish?

  10. #40
    Registered User
    Join Date
    Dec 2003
    Posts
    53
    in the order of your questions starting from do you need a for loop
    yes, it's good programming practise to do so, *shrugs* could be anything, depending on how you want to use it, you should stop treating usedchars as a string.

    last answer in detail because it's the one where I can do the most good.
    as you know by now, strings == char arrays.
    However, I think you are not yet aware of what that really means when printing stuff out.
    here's a crash course of the printf format conversion specifier:
    %c == print out one character
    %s == prints out an array of character that must be terminated by a '\0' character

    if the string, aka array of characters, is not terminated by a '\0' character, and you print it out using the %s, printf won't know where to stop and will keep printing until it hits a value in your computer's memory that looks like '\0' to it, hence the gibberish that you're getting.
    /*** EDIT ***/
    For that matter, your for loop also won't know where to stop if you didn't manually insert a '\0' into the array...
    /*** END EDIT ***/

    try replacing the line
    printf("%s", usedchars);
    with this
    printf("%c", usedchars[k]);

    as a suggestion, since I'm assuming that you are using this function before you call the checkchar function, try to get this function to return the character if it hasn't been used before, and return a 0 if a match is found.
    Last edited by tzuchan; 04-01-2004 at 11:12 AM.

  11. #41
    Registered User
    Join Date
    Jan 2004
    Posts
    50
    So is there an easy way that i can add a terminating character to the end of the string? printing the characters out in that method you suggest still turns up rubbish, I've altered the loop to only run through a maximum of 10 times too.

    Code:
    int usedcharacters (char usedchars [], char let2bg)
    	{
    
    	int k;
    	for (k = 0; k <= 10; k++)
    	
    	{
    		if (let2bg = usedchars[k])
    		{
    		
    		printf ("%c", usedchars [k]);
    		}
    	else
    		k++;
    
    
    		}
    return usedchars [k];
    	}
    Even before it returns anything all i get is rubbish, just what the hell is wrong with this loop, I've being stuck on the same thing for about 4 hours now

  12. #42
    Registered User
    Join Date
    Dec 2003
    Posts
    53
    if (let2bg = usedchars[k])
    That should have been
    if (let2bg == usedchars[k])
    it's one of the easier to make programming errors...
    Also, you can try initializing the array with '*'s or ' 's so that it's not containing random data.

    One more thing, are you updating the array to contain the latest non repeated letter?

    Going to dash of a function for you. no promises about being bug free, but at least you can try the logic.
    Code:
    char usedcharacters(char input, char used[])
    {
    
    int i; for(i = 0; used[i] != '\0' && used[i] != input; i++); //<- must have semicolon here. //The above for loop loops until either it hits the end of data or used character if(used[i] == '\0') // If this is true, input is a new character {
    used[i] = input; // stores latest input used[i+1] = '\0' // ensures that the next element is the string terminator return input; // returns the character so you can use it in the checkchar function
    } else {
    return '\0'; // returns 0 so that you can use if(usedcharacters(...) == '\0') to check state
    }
    }

  13. #43
    Been here, done that.
    Join Date
    May 2003
    Posts
    1,164
    How's this for an idea:

    What's the absolute maximum of guesses you can have? 26!
    A 26 character array initialized to TRUE can be used to represent all letters not guessed.

    Each time a letter is guessed
    -- Test the corresponding array element for FALSE.
    -- If it's TRUE, set the corresponding array element to FALSE.
    -- If FALSE, error
    Last edited by WaltP; 04-01-2004 at 02:02 PM.
    Definition: Politics -- Latin, from
    poly meaning many and
    tics meaning blood sucking parasites
    -- Tom Smothers

  14. #44
    Registered User
    Join Date
    Jan 2004
    Posts
    50
    Is this what you are meaning to do tzuchan?

    Code:
    int usedcharacters (char usedchars [], char let2bg)
    {
     
    	int k;
    	for(k = 0; usedchars[k] != '\0' && usedchars[k] != let2bg; k++); /*loop until end character is not null and is not the character to be searched */
    	{
    		if(usedchars[k] == '\0')  /*if at end of the array*/
    		{
    			usedchars[k] = let2bg; /* adds guessed character to that which is being searched */
    			usedchars[k+1] = '\0'; /* adds null value so string can be searched again */
    			printf ("%c", usedchars [k]); /*prints what used characters there are that have already being searched*/
    			return usedchars [k]; /*returns used character*/
    		}
    		else /*if the character is not at end i.e first character guessed*/
    		{
    			return '\0';	/*add null value so can be searched again */
    		}
    	}
     
    }
    Its a great piece of code but how can i store the value so that it wont disappear when i leave the function? what do you mean by " if(usedcharacters(...) == '\0')"?

    **** EDIT ****

    Ok running this thing through the debugger for some bizarre reason (i have no idea why) the letter K is assigned the value 12 as soon as it enters the for loop, any idea why this is? I changed it back to zero in the debugger and it seems to work fine?
    Last edited by petedee; 04-01-2004 at 02:44 PM.

  15. #45
    Registered User
    Join Date
    Dec 2003
    Posts
    53
    As long as you pass in the usedchars array from the main function and you initialize it as
    usedchars[maxnumofguess+1] = "";
    the usedchars array will become your store of which characters have been entered before.

    first of all, depending on how you initialized your usedchars (in my logic, usedchars starts of being empty, with usedchar[0] == '\0'), you should get k != 0.

    for(k = 0; usedchars[k] != '\0' && usedchars[k] != let2bg; k++); //<--the semicolon here results in k running from 0 until when then condition is met without excuting anysort of codes.

    Code:
    int usedcharacters (char usedchars [], char let2bg)
    {
     
    	int k;
    	for(k = 0; usedchars[k] != '\0' && usedchars[k] != let2bg; k++); 
    /*loop until character is not null or is not the character to be searched */
    	{
    		if(usedchars[k] == '\0')  /*if at end of the array*/
    		{
    			usedchars[k] = let2bg; 
    /* adds guessed character to list of characters that user has pressed*/
    			usedchars[k+1] = '\0';
    /* adds null value so string can be searched again */
    			printf ("%c", usedchars [k]); 
    /* This line only prints one character if and only if it hasn't been entered before*/
    			return usedchars [k]; /*returns character that hasn't been used before*/
    		}
    		else /*if the character is not at end i.e first character guessed*/
    		{
    			return '\0';	
     /*returns a null value so that you can tell if the character has been used before. */
    		}
    	}
     
    }
    this function returns a char value. if the char value is not equal (usedcharacter(...) != '\0') to null, it means that the character that is returned by the function is a new one and should be taken into the checkchar function.

    if the char value is equal(usedcharacter(...) == '\0') to null, that means that the user has entered the character that you passed in to check before, hence you should tell him that "Oops! you tried this letter before. Please enter another letter."
    Last edited by tzuchan; 04-01-2004 at 04:38 PM.

Popular pages Recent additions subscribe to a feed