Thread: input control question

  1. #16
    Banned
    Join Date
    Oct 2008
    Posts
    1,535
    i did that
    its still gives the same bug

    Code:
    #include <stdio.h>
    
    #define N 9
    int checkEndOfGame(char board[N][N],int size);
    void sprint(char board[N][N],int size);
    int same_digit(char ch_cords[40],int k);
    int is_valid(const char input[40],int leng);
    void mainPlayGame(char board[N][N]);
    int playGame(char board[N][N],int size);
    void printBoard(char board[N][N],int size);
    int removeMine(char board[N][N],int size,int x,int y);
    void mainMenu();
    int unCover(char board[N][N],int size,int x,int y);
    
    int main()
    {
        char board[N][N];
        mainPlayGame(board);
        printf("bye, please press enter to exit!\n");
        getchar();
        return 0;
    }
    
    void mainPlayGame(char board[N][N])
    {
    	int x_cord,y_cord,wins=0,loses=0;
    
        char input[40];
        char input2[40];
        int flag2=0;
        int opt,leng,size=-1;
        int index,kndex;
        char ch_cords[40];
        int tr;
        int cords[8][2];
        int tndex,result;
        int i,k,j,ch,l,x_rem,y_rem;
    
    
    	         for(index=0;index<N;index++)
                 {
                    for(kndex=0;kndex<N;kndex++)
                    {
                        board[index][kndex]=' ';
                    }
                 }
    
    
    
        do
        {///
            mainMenu();
            scanf("%d",&opt);
            while((l= getchar()) != '\n');
    
    		if ((opt<0)||(opt>9))
               {
    			    
    		}
    		else
    		{
            if (opt==1)
            {
                 for(index=0;index<N;index++)
                 {
                    for(kndex=0;kndex<N;kndex++)
                    {
                        board[index][kndex]=' ';
                    }
                 }
                printf("enter board size [1..9] (no input control is needed):\n");
                scanf("%d",&size);
    			while((l= getchar()) != '\n');
            }
    
            if (opt==2)
            {
                flag2=0;
                if (size==-1)
                {
                    printf("you must choose board size first!\n");
                }
            else
            {
                printf("enter x,y of the new mines (x1,y1)(x2,y2)...(xn,yn)\n");
                for (i = 0; i < 39 && (ch = getchar()) != '\n' && ch >=0; ++i)
                {
                    input2[i] = ch;
                }
    
                input2[i] = '\0';
                k=0;
               for(index=0;index<=i;index++)
               {
                   if(input2[index]!=' ')
                   {
                       input[k]=input2[index];
                       k++;
                   }
               }
    
               leng=k;//same digit input check
               if (is_valid(input,leng))
               {
    			   for(index=0;index<leng;index++)
                   {
                     if (((input[index])>='0')&&((input[index])<='9')&&((input[index+1])>='0')&&((input[index+1])<='9'))
                       {
    	                  flag2=1;
                       }
    			   }
                   k=0;
               if (flag2!=1){
               for(index=0;index<leng;index++)
               {
                   if((input[index]!='(')&&(input[index]!=',')&&(input[index]!=')'))
                   {
                       ch_cords[k]=input[index];
                       k++;
                   }
               }
    		   k--;
    
    
               tndex=0;
               for(index=0;index<=leng;index++)
               {
                   if((input[index]==')'))
                   {
                       tndex++;
    
                   }
               }
    
    
                j=0;
                for(index=0;index<tndex;index++)
                {
                    for(kndex=0;kndex<2;kndex++)
                    {
                        tr=ch_cords[j]-'0';
                        cords[index][kndex]=tr;
                        j++;
                    }
                }
    
    
                result=same_digit(ch_cords,tndex); //i call the function here
    			if (result==0)
    			{
                   for(index=0;index<tndex;index++)
                   {
    
    
    						x_cord=cords[index][0];
    						y_cord=cords[index][1];
                    if((x_cord>size)||(y_cord>size)||(y_cord<0)||(x_cord<0))
    
                    {
                     //out of bound
                     printf("(%d,%d) is out of range\n",x_cord,y_cord);
                    }
                    else
                    {  //excepted
                      if (board[y_cord-1][x_cord-1]==' ')
                      {
                      board[y_cord-1][x_cord-1]='*';
                      printf("(%d,%d) mine inserted\n",x_cord,y_cord);
                      }
                      else
                      {
                          printf("(%d,%d) already full\n",x_cord,y_cord);
                      }
                    }
    
                   }
    
    			}
    
               }
               else
               {
                 printf("wrong input\n");
               }
    
           }
           else
           {
               printf("wrong input\n");
           }
    
           }
    
         }//end if opt 2///
         if (opt==3)
         {
             if (size==-1)
                {
                    printf("you must choose board size first!\n");
                }
            else
            {
                 printf("enter x,y of the  mine to remove (no input control is needed):\n");
                for (i = 0; i < 39 && (ch = getchar()) != '\n' &&  ch >=0; ++i)
                {
                    input2[i] = ch;
                }
    
                input2[i] = '\0';
    
    
                       ch_cords[0]=input2[0];
                       ch_cords[2]=input2[2];
                       x_rem=ch_cords[0]-'0';
                       y_rem=ch_cords[2]-'0';
                       if (board[y_rem-1][x_rem-1]!='*')
                       {
                          printf("wrong input or no mine\n");
                       }
                       else
                       {
                           printf("mine removed\n");
                           board[y_rem-1][x_rem-1]=' ';
                       }
            }
         }
         if (opt==4)
         {
             if (size==-1)
                {
                    printf("you must choose board size first!\n");
                }
            else
            {
           printBoard(board,size);
            }
         }
         if (opt==5)
         {
       tr=playGame(board,size);
       if (tr==1){
           wins++;
           }
       if (tr==0){
        loses++;
       }
         }
    
         if (opt==0)
         {
             printf("you played %d games(s):\n",wins+loses);
              printf("you won %d\n",wins);
              printf("you lost %d\n",loses);
              printf("bye!");
         }
    	 }
        }while(opt!=0);
    }
    
    
    
    
    
    int same_digit(char ch_cords[40],int k)
    {
        int index;
        char ch;
        ch=ch_cords[0];
        for (index=0;index<=k;index++)
        {
          if (ch_cords[index]!=ch)
    	  {
    		  return 0;
    	  }
    
        }
        if(k>2)
        {
    	   return 1;
        }
        else
        {
         return 0;
        }
    }//end same digit
    
    void mainMenu()
    {
    
    
        printf("--------------------------\n");
        printf("welcome to the game\n");
        printf("1. choose board size\n");
        printf("2. place mines\n");
        printf("3. remove mines\n");
        printf("4. show mines\n");
        printf("5. start the game\n");
        printf("0. exit\n");
        printf("please enter your choice (input control is needed): \n");
    
    }
    
    
    
    void printBoard(char board[N][N],int size)
    {
        int index,kndex;
        for(index=0;index<size;index++)
        {
    		printf("+");
           for(kndex=0;kndex<size;kndex++)
           {
               printf("-+");
           }
           printf("\n");
    	   printf("|");
           for(kndex=0;kndex<size;kndex++)
           {
               printf("%c|",board[index][kndex]);
           }
           printf("\n");
    
     }
    	printf("+");
      for(kndex=0;kndex<size;kndex++)
      {
             printf("-+");
    
      }
      printf("\n");
    }
    
    int removeMine(char board[N][N],int size,int x,int y)
    {
        if (board[y-1][x-1]=='*')
        {
            board[y-1][x-1]=' ';
            printf("mine removed");
            return 1;
        }
        else
        {
            printf("wrong input or no mine");
            return 0;
        }
    
    
    }
    
    
    int unCover(char board[N][N],int size,int x,int y){
     int count=0;
      if (board[y-1][x-1]=='*'){
       printf("you lost\n");
       board[y-1][x-1]='X';
    
       return 0;
      }
     else
     {
    
    
          if (((y-2)>=0) && ((x-2)>=0) && (board[y-2][x-2]=='*')){
           count++;
          }
    
            if (((y-2)>=0) && ((x-1)>=0) && (board[y-2][x-1]=='*')){
           count++;
          }
            if (((y-2)>=0) && ((x)<size) && (board[y-2][x]=='*')){
           count++;
          }
    
    
          if (((y)<size) && ((x-2)>=0) && (board[y][x-2]=='*')){
           count++;
          }
    
            if (((y)<size) && ((x-1)>=0) && (board[y][x-1]=='*')){
           count++;
          }
            if (((y)<size) && ((x)<size) && (board[y][x]=='*')){
           count++;
          }
          if (((y-1)>=0) && ((x-2)>=0) && (board[y-1][x-2]=='*')){
           count++;
          }
          if (((y-1)>=0) && ((x)<size) && (board[y-1][x]=='*')){
           count++;
          }
    
           board[y-1][x-1]='0' +count;
    
       return 1;
    
     }
    }
    
    
    
    
    int is_valid(const char input[40],int leng)
    {
    	int flag=3;
    	int i=1;
        int index;
        for(index=0;index<leng;index++)
        {
            if((input[index]!='(')&&(input[index]!=',')&&(input[index]!=')'))
            {
                if (((input[1])<'0')||((input[1])>'9'))
                {
    		        return 0;
    	        }
            }
        }
        if (input[0] != '(')
        {
            flag=0;
        }
        if (((input[1])<'0')||((input[1])>'9'))
        {
    	    flag=0;
        }
        i++;
        while((input[i]<='9')&&(input[i]>='0'))
        {
            i++; //increasing the  address by1
        } //it wiil get char '2'
        if (input[i] == ',')
        {   //'2' differs ','
            if (((input[i+1])<'0')||((input[i+1])>'9'))
            {
    		   flag=0;
    	    }
            i++;
            while((input[i]<='9')&&(input[i]>='0'))
            {
                input++; //increasing the  address by1
            }
            if (input[i]==')')
            {
                i++;
            }
            else
              flag=0;
            }
       else
       {
          flag=0;
       }
    
       if (flag ==0)
       {
           return 0;
       }
    
    
        while (input[i]!= '\0')
        {
            if (input[i] != '(')
            {
                flag=0;
            }
    	    if (((input[i+1])<'0')||((input[i+1])>'9'))
    	    {
    		   flag=0;
    	    }
    	        i++;
            while((input[i]<='9')&&(input[i]>='0'))
            {
    
                i++; //increasing the  address by1
            } //it wiil get char '2'
    
            if (input[i] == ',')
            {   //'2' differs ','
                if (((input[i+1])<'0')||((input[i+1])>'9'))
                {
    		        flag=0;
    	        }
                i++;
                while((input[i]<='9')&&(input[i]>='0'))
                {
                    i++; //increasing the  address by1
                }
                if (input[i]==')')
                {
                    i++;
                }
                else
                flag=0;
                }
       else
       {
          flag=0;
       }
       if (flag ==0)
            {
                return 0;
            }
        }
        return 1;
    }
    
    
    int checkEndOfGame(char board[N][N],int size){
     int index,kndex;
    
     for (index=0;index<size;index++){
         for (kndex=0;kndex<size;kndex++){
         if  (board[index][kndex]==' '){
          return 0;
         }
         }
     }
     return 1;
    }
    
    void sprint(char board[N][N],int size)
    {
        int index,kndex;
        for(index=0;index<size;index++)
        {
    		printf("+");
           for(kndex=0;kndex<size;kndex++)
           {
               printf("-+");
           }
           printf("\n");
    	   printf("|");
           for(kndex=0;kndex<size;kndex++)
           {
               if ((board[index][kndex]=='*')||(board[index][kndex]==' '))
               {
            printf("?|");
               }
               else
               {
               printf("%c|",board[index][kndex]);
               }
           }
           printf("\n");
    
     }
    	printf("+");
      for(kndex=0;kndex<size;kndex++)
      {
             printf("-+");
    
      }
      printf("\n");
    }
    
    int playGame(char board[N][N],int size){
    int x_rem,y_rem,i,ch,kent,wins=0,loses=0,end,tr;
    char input2[40];
              if (size==-1)
                {
                    printf("you must choose board size first!\n");
                }
            else
            {
             do
             {
    
                 printf("enter a square x,y to uncover : (no input control is needed):\n");
                for (i = 0; i < 39 && (ch = getchar()) != '\n' && ch >=0; ++i)
                {
                    input2[i] = ch;
                }
    
                   input2[i] = '\0';
                   x_rem=input2[0]-'0';
                   y_rem=input2[2]-'0';
    
                    kent=unCover(board,size,x_rem,y_rem);
    
                if (kent==0){
              end=1;
              loses++;
    
              printBoard(board,size);
             }
             else{
    
             tr=checkEndOfGame(board,size);
             if (tr==0)
             {
                sprint(board,size);
             }
             else
             {
                 printBoard(board,size);
                 end=1;
                 printf("all mines were uncovered - you won\n");
                 wins++;
             }
             }
    
    
    
             }while(end!=1);
            }
    
        if (wins==1){
         return 1;
        }
    
        {
            return 0;
        }
    }

  2. #17
    ... kermit's Avatar
    Join Date
    Jan 2003
    Posts
    1,534
    You need to slow down and think about the logic. Read my previous post.

  3. #18
    Banned
    Join Date
    Oct 2008
    Posts
    1,535
    you said that i need to check the scanf regarding its value
    that what i did
    in the condition

    how i am doing it wrong?

  4. #19
    Jack of many languages Dino's Avatar
    Join Date
    Nov 2007
    Location
    Chappell Hill, Texas
    Posts
    2,332
    scanf() returns the number of formatting variable patterns satisfied. It's an int. Do something like...
    Code:
    int rc, var ; 
    rc = scanf("%d", &var) ; 
    if (rc != 1) { ...send error message, empty input buffer, repeat the request for data .... }
    Mainframe assembler programmer by trade. C coder when I can.

  5. #20
    ... kermit's Avatar
    Join Date
    Jan 2003
    Posts
    1,534
    that what i did
    Nope. Look at my previous example. scanf returns an int. You can use that return value to check if you successfully got what you are looking for. The check you did is a good idea, but it is only good if the user enters an INTEGER. If the user enters characters, then scanf fails. How do you know if scanf fails? Check the return value. If you call scanf looking for one integer, and it does not return the value 1, then scanf failed.

  6. #21
    Banned
    Join Date
    Oct 2008
    Posts
    1,535
    like this??
    i presumed that scanf returns some value

    Code:
    int flag;
    
    flag=scanf("%d",&opt);
    
    if (flag==1)
     {
       /go to program
     }
    else
     {
     do nothing
    }

  7. #22
    ... kermit's Avatar
    Join Date
    Jan 2003
    Posts
    1,534
    Generally speaking, you have got the idea, though I would try a new variable name. I think you already use the variable 'flag' in your code. Try something like 'retval.' But yes, you have got it. If the return value of scanf is 1, then the user entered an integer. But even if the user entered an integer, it might be the wrong one. So while you are at it, check the range of that integer with your

    Code:
    if ((opt<0)||(opt>5))
    To summarise, if the return value of scanf is not 1, or if the number is an integer, but outside of the range of choices, tell the user what input you expect, and send them back to try again.
    Last edited by kermit; 01-07-2009 at 01:13 PM.

  8. #23
    Banned
    Join Date
    Oct 2008
    Posts
    1,535
    it works thanks

    i didnt add
    Code:
    if ((opt<0)||(opt>5))
    because in that case its just wont go to any of these options
    and will show the loop again
    am i correct??
    Last edited by transgalactic2; 01-07-2009 at 09:52 AM.

  9. #24
    ... kermit's Avatar
    Join Date
    Jan 2003
    Posts
    1,534
    Well however you code it, just think in these terms: Assume the user will enter the input wrong. In this way, you can think of how to check their input to see if it is what you want. Don't let the user away with anything! I realise this is just a project program, but if you are going to be doing programming for a living, its beneficial to start mastering these ideas now. As well, even if you don't use functions like strtol for input on your project, play around with it a bit on your own time. You will learn a lot

  10. #25
    Banned
    Join Date
    Oct 2008
    Posts
    1,535
    thanks

  11. #26
    Registered User
    Join Date
    Nov 2008
    Location
    Phoenix
    Posts
    70
    Quote Originally Posted by kermit View Post
    Nope. Look at my previous example. scanf returns an int. You can use that return value to check if you successfully got what you are looking for. The check you did is a good idea, but it is only good if the user enters an INTEGER. If the user enters characters, then scanf fails. How do you know if scanf fails? Check the return value. If you call scanf looking for one integer, and it does not return the value 1, then scanf failed.
    Quote Originally Posted by transgalactic2 View Post
    like this??
    i presumed that scanf returns some value

    Code:
    int flag;
    
    flag=scanf("%d",&opt);
    
    if (flag==1)
     {
       /go to program
     }
    else
     {
     do nothing
    }
    What perfect timing. This was bugging me in a program I made last month, but came back to last night to solve the input issues for. I googled around for a while looking for a solution to how I could make sure the user only entered numbers for input. I had a two option menu that I was able to fix by switching from a scanf for a char, to getchar (this was separate from the numbers-only problem and had different behavior for unexpected input). How to only get numbers for input in prompts later in the program however, either ignoring or discarding characters, was stumping me. It's not like there's a getnum, to my knowledge (after one quarter of intro C, just finished).

    This saved me from having to ask. It had never occurred to me to use scanf's return value. I was about to try gets with sscanf, but it seemed overly complicated and seemed like it might not even work well anyways.

    Thanks guys.

  12. #27
    ... kermit's Avatar
    Join Date
    Jan 2003
    Posts
    1,534
    Quote Originally Posted by Sorin View Post
    It's not like there's a getnum, to my knowledge (after one quarter of intro C, just finished).
    But nothing prevents you from writing your own.

    Quote Originally Posted by Sorin View Post
    This saved me from having to ask. It had never occurred to me to use scanf's return value. I was about to try gets with sscanf, but it seemed overly complicated and seemed like it might not even work well anyways.
    Some people will suggest sscanf over scanf, and its true that this can be more robust as it gives a measure of extra control over the input, but at no time should you ever use gets. gets cannot be made safe. Read this. If you are not convinced yet, come on back, and we will try harder.

    As for the return value of scanf, it ought to go without saying that if you are going to try using a function, have a look at your documentation on how it is used, what values it returns and so on. If you are using a *nix machine, such as OpenSolaris, or FreeBSD or Linux, you can just type man scanf at the command prompt, and it will bring up the manual page for that function. If you are running Windows, you can use this web page (or ones like it) to search for documentation on various functions. The Linux documentation for various Standard Library functions is usually adequate.

  13. #28
    Registered User
    Join Date
    Nov 2008
    Location
    Phoenix
    Posts
    70
    Quote Originally Posted by kermit View Post
    But nothing prevents you from writing your own.
    Not that smart yet.

    Quote Originally Posted by kermit View Post
    Some people will suggest sscanf over scanf, and its true that this can be more robust as it gives a measure of extra control over the input, but at no time should you ever use gets. gets cannot be made safe. Read this. If you are not convinced yet, come on back, and we will try harder.
    I actually haven't gotten to strings at all yet. My intro class didn't cover it (the next level of the class does). But I'll keep that link and what you said in mind (gets vs fgets).

    Quote Originally Posted by kermit View Post
    As for the return value of scanf, it ought to go without saying that if you are going to try using a function, have a look at your documentation on how it is used, what values it returns and so on. If you are using a *nix machine, such as OpenSolaris, or FreeBSD or Linux, you can just type man scanf at the command prompt, and it will bring up the manual page for that function. If you are running Windows, you can use this web page (or ones like it) to search for documentation on various functions. The Linux documentation for various Standard Library functions is usually adequate.
    Well I knew about it's return value; it just never occurred to me to actually use it as a condition for getting valid input. I know it's technically a function, but up to now I really hadn't seen it as anything other than a means to get input. Thinking outside the box and more carefully analyzing things are things that I'm working on.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. quick noob question
    By thanatos1 in forum C# Programming
    Replies: 2
    Last Post: 06-17-2009, 08:28 PM
  2. RickEdit control question
    By nomer in forum Windows Programming
    Replies: 6
    Last Post: 03-03-2006, 07:00 PM
  3. Restricting input to an edit control
    By bennyandthejets in forum Windows Programming
    Replies: 7
    Last Post: 10-05-2003, 01:10 AM
  4. Tab Controls - API
    By -KEN- in forum Windows Programming
    Replies: 7
    Last Post: 06-02-2002, 09:44 AM
  5. Input Control
    By Unregistered in forum C++ Programming
    Replies: 11
    Last Post: 01-15-2002, 06:21 PM