Page 1 of 1

Reading Chess Position[SOLVED]

Posted: Sun Jul 20, 2014 11:02 pm
by Benjamin100
Having some trouble reading in chess positions.
Reading the character as "x", and the number as "y".
This "sscanf_s" function ends up with some access violation.
I have no idea why.
Here is the function.

Code: Select all

char inputX;
		int inputY;
		std::string input;
		std::getline(std::cin, input);
		sscanf_s(input.c_str(),"%c %d", &inputX, &inputY); 

Re: Reading Chess Position [SORT OF SOLVED]

Posted: Sun Jul 20, 2014 11:40 pm
by Benjamin100
Ok. It works when I just disable the warning about "sscanf" and just use the standard version.
Apparently it is some trouble with "sscanf_s". Does use the parameters differently than the old version>

Re: Reading Chess Position

Posted: Mon Jul 21, 2014 1:00 am
by X Abstract X
Haven't personally used these functions but what happens if you switch it to:

sscanf_s(input.c_str(),"%c %d", &inputX, sizeof(inputX), &inputY);

Re: Reading Chess Position

Posted: Mon Jul 21, 2014 5:53 pm
by dandymcgee
X Abstract X wrote:Haven't personally used these functions but what happens if you switch it to:

sscanf_s(input.c_str(),"%c %d", &inputX, sizeof(inputX), &inputY);
That looks right based on what I just read at http://msdn.microsoft.com/en-us/library/t6z7bya3.aspx.
MSDN wrote:Unlike the less secure version sscanf, a buffer size parameter is required when you use the type field characters c, C, s, S, or string control sets that are enclosed in []. The buffer size in characters must be supplied as an additional parameter immediately after each buffer parameter that requires it.
// crt_sscanf_s.c
// This program uses sscanf_s to read data items
// from a string named tokenstring, then displays them.

#include <stdio.h>
#include <stdlib.h>

int main( void )
{
   char  tokenstring[] = "15 12 14...";
   char  s[81];
   char  c;
   int   i;
   float fp;

   // Input various data from tokenstring:
   // max 80 character string plus NULL terminator
   sscanf_s( tokenstring, "%s", s, _countof(s) );
   sscanf_s( tokenstring, "%c", &c, sizeof(char) );
   sscanf_s( tokenstring, "%d", &i );
   sscanf_s( tokenstring, "%f", &fp );

   // Output the data read
   printf_s( "String    = %s\n", s );
   printf_s( "Character = %c\n", c );
   printf_s( "Integer:  = %d\n", i );
   printf_s( "Real:     = %f\n", fp );
}

Re: Reading Chess Position

Posted: Thu Jul 24, 2014 12:04 am
by Benjamin100
Thanks for the info guys.
I was fixing up some of the code and then started having trouble with input again, (which I wasn't having before.) Now taking in the name as two characters, I have trouble with the loop. It takes the first input entered, and moves accordingly. But then any input after, I ask it to print out the first letter and it comes up blank. Why would "scanf" make the characters at the addresses null the second time around?

Re: Reading Chess Position

Posted: Thu Jul 24, 2014 5:00 pm
by Benjamin100
Well apparently the "scanf" function just doesn't work very well with getting inputs in a loop.
Ended up using "sscanf" with an input string instead.
Now it works.

Re: Reading Chess Position

Posted: Fri Jul 25, 2014 3:06 pm
by X Abstract X
Benjamin100 wrote:Well apparently the "scanf" function just doesn't work very well with getting inputs in a loop.
Ended up using "sscanf" with an input string instead.
Now it works.
I think the problem you're having is because scanf will just read the newline character the second time you call it. You can tell it to ignore white space by adding a space before to indicate that it should ignore whitespace: scanf(" %c", &c); Or, you can use scanf(%c\n", &c);

Re: Reading Chess Position[SOLVED]

Posted: Fri Jul 25, 2014 4:07 pm
by bbguimaraes
There are two things you have to pay attention to (taken from scanf(2)'s man page):
  • scanf reads until it finds whitespace (space, newline, etc.).
  • If a pattern is not matched, scanf stops reading the input.
Say I have the following code:
while(1) {
    int ret, i1, i2;
    scanf("%d %d", &i1, &i2);
    if(i1 == 1 && i2 == 2)
        break;
}
If I give the string "1 b\n" as input (remeber the "enter" key is used to flush the terminal buffer but it is also present on the input), this is what happens:

Code: Select all

- Input string:
inputstring = "1 b\n";

- scanf tries to read the first part of the pattern ("%d") and is successful, yielding (roughly):
i1 = 1;
inputstring = " b\n";

- scanf tries to read the second part of the pattern (" ") and is successful, so the space is removed from the buffer.
inputstring = "b\n";

- scanf tries to read the third part of the pattern ("%d"), but fails. The input is unchanged.
This will leave the buffer as "b\n". You can check this by putting this before the end of the loop:
char buffer[1024];
scanf("%s", &buffer);
printf("--%s--\n", buffer);
scanf("%s", &buffer);
printf("--%s--\n", buffer);

Code: Select all

1 b
--b--
--
--
What happened here is the first scanf read the remaing "b" on the input and stopped at the newline (whitespace). The second scanf started reading, got the newline and stopped at the end of the input.

But consider what happens if you don't include these two scanf's. The input buffer still contains "b\n" and we are back at the head of the loop. scanf will try to read the first pattern ("%d"), fail and bail out, because of the first rule on the beginning of this post. The test will keep failing, because i1 and i2 still have their old values (1 and undefine, respectively). Bottom line: you're stuck on an infinite loop.