scanf_s error visual studio - c++

int setN, setN2;
char sign;
scanf_s("do %d %c %d", &setN, &sign, &setN2);
I'm input "do 1 + 3", for example, and program in vs fall with an error "Unhandled exception at 0x650de541 in disc_II_2_1.exe: 0xC0000005: Access violation writing location 0xc96ff41e".
P.S. code below get the same result.
scanf_s("do %d %c %d", &setN, &sign, &setN2, 8);
What am I doing wrong?

From MSDN:
Unlike scanf and wscanf, scanf_s and wscanf_s require the buffer size
to be specified for all input parameters of type c, C, s, S, or string
control sets that are enclosed in []. The buffer size in characters is
passed as an additional parameter immediately following the pointer to
the buffer or variable.
and later
In the case of characters, a single character may be read as follows:
char c;
scanf_s("%c", &c, 1);
At the end of that reference, there are also a few examples where you may see that:
the count argument should appear immediately after the corresponding input
the count argument should correspond to the maximum number of expected char (or as stated above for a single char, it should be 1)
So, in your particular case you should have:
scanf_s("do %d %c %d", &setN, &sign, 1, &setN2);

Related

swscanf can't read integer value

std::wifstream ifstream("JobList.txt");
ifstream.imbue(std::locale(std::locale::empty(), new std::codecvt_utf8<wchar_t>));
if (!ifstream.is_open()) {
std::cout << "파일을 찾을 수 없습니다!" << std::endl;
return 0;
}
std::wstring s;
wchar_t name[20];
int priority{};
int workingTime{};
int requestTime{};
while (ifstream) {
std::getline(ifstream, s);
swscanf(s.data(), L"%[^',']s, %d, %d, %d", name, &priority, &workingTime, &requestTime);
mRequestArrivationQueue.emplace(name, priority, workingTime, requestTime);
}
ifstream.close();
This is JobList.txt file
Good Boy, 1, 2, 5
도서 대출, 1, 2, 13
swscanf read only first wstring(name), but it doesn't read rest integer values
There is a little error in your code and a terrible (even if common) bad practice.
The error in that the conversion format specifier is [set] and it shall not be followed with a s. Here the format string requires a s character afer the first field (which is impossible) so the conversions stops after decoding the first field. The fix is trivial, remove that offending s (and the useless quotes, thanks to #AdrianMole for his comment):
swscanf(s.data(), L"%[^,], %d, %d, %d", name, &priority, &workingTime, &requestTime);
And the terrible practice is to fail to test the return value of a scanf family function. Had you tested it, you would have immediately found that it was 1 and that only the first field had been decoded.
IMHO, unless you are a C programmer and have used the C io functions for a long time, you should better use a C++ [w]stringstream. The syntax is not easier, but error detection is better...

What is proper size of buffer when using sprint()?

What is proper size of an char array (buffer) when i want to use sprintf function?
I dont know why this part of code is working if buffer can hold only 1 char? I put a lot more chars inside than 1.
/* sprintf example */
#include <stdio.h>
int main ()
{
char buffer[1];
int n, a=5, b=3;
n = sprintf (buffer, "%d plus %d is %d", a, b, a+b);
printf ("[%s] is a string %d chars long\n", buffer, n);
return 0;
}
Results:
[5 plus 3 is 8] is a string 13 chars long
What is proper size of an char array (buffer) when i want to use sprintf function?
There isn't one.
If you can work out an upper bound from the format string and types of input, then you might use that. For example, a 32-bit int won't take up more than 11 characters to represent in decimal with an optional sign, so your particular example won't need more than 44 characters (unless I miscounted).
Otherwise, use something safer: std::stringstream in C++, or snprintf and care in C.
I don't know why this part of code is working if buffer can hold only 1 char?
It isn't. It's writing past the end of the buffer into some other memory.
Maybe that won't cause any visible errors; maybe it will corrupt some other variables; maybe it will cause a protection fault and end the program; maybe it will corrupt the stack frame and cause all kinds of havoc when the function tries to return; or maybe it will cause some other kind of undefined behaviour. But it's certainly not behaving correctly.
In your code a buffer overflow occurred, there were no apparent consequences, but that doesn't mean it worked correctly, try using a memory debugger like valgrind and you will see what I mean.
You can't ensure that sprintf() will not overflow the buffer, that's why there is a snprintf() function to which you pass the size of the buffer.
Sample usage
char buffer[100];
int result;
result = snprintf(buffer, sizeof(buffer), "%d plus %d is %d", a, b, a + b);
if (result >= sizeof(buffer))
{
fprintf(stderr, "The string does not fit `buffer'.\n");
}
Assuming code must use sprintf() and not some other function:
pre-determine the worse case output size and add margin.
Unless there are major memory concerns, suggest a 2x buffer. Various locales can do interesting things like add ',' to integer output as in "123,456,789".
#include <stdio.h>
#include <limits.h>
#define INT_DECIMAL_SIZE(i) (sizeof(i)*CHAR_BIT/3 + 3)
#define format1 "%d plus %d is %d"
char buffer[(sizeof format1 * 3 * INT_DECIMAL_SIZE(int)) * 2];
int n = sprintf(buffer, format1, a, b, a + b);
A challenging example is when code tries sprintf(buf,"%Lf", some_long_double) as the output could be 1000s of characters should x == LDBL_MAX. About 5000 characters with binary128 as long double.
// - 123.............456 . 000000 \0
#define LDBL_DECIMAL_SIZE(i) (1 + 1 + LDBL_MAX_10_EXP + 1 + 6 1)

Scanning an integer using %c and a character using %d: unexpected results

I am unable to give a proper reason for the following code's output. Can anybody help me.
int main()
{
int i;
char ch;
scanf("%c",&i);
scanf("%d",&ch);
printf("%d\n%c",i,ch);
return 0;
}
input output:
input:
a
45
output:
0
-
You're reading an int into a char. Assuming that sizeof(int) != sizeof(char), this will result in scanf writing beyond the end of ch with undefined consequences.
You should use the %i format specifier for int arguments and the %c for char arguments
int main()
{
int i;
char ch;
scanf("%c",&ch);
scanf("%d",&i);
printf("%d\n%c",i,ch);
return 0;
}
Don't lie to scanf or printf. Nothing good ever comes out of it.
In this case, you are trying to stuff 4 bytes into the space of 1 - which obviously doesn't work, however much you squeeze. The fact that your program doesn't crash is purely luck.
This is Undefined behavior.You are trying to confuse compiler by telling that to pop and push something different what exactly it should in printf and scanf statement respectively.

Random characters when reading from pipe

In the following code :
...
char *message = "This is the message!";
...
printf("Writing to file descriptor FD[%i] \n", fd[1]);
write( fd[1], message, strlen(message));
printf("Reading from file descriptor FD[%i] \n", fd[0]);
read( fd[0], buffer, strlen(message));
printf("Message from FD[%i] : \"%s\" .\n", fd[0], buffer);
I get the following output :
"This is the message!���" .
But if I remove the "!" from my message, the output doesn't have random characters... Any idea why I get these 3 random characters to appear?
When you write your message of length strlen(whatever), that does not include the terminating NUL character. Hence what comes out at the other end is not a C string but rather just a collection of characters.
What follows that collection of characters in memory depends entirely upon what was there before you read them from the pipe. Since it's not a C string (except by possible accident if the memory location following just happened to already contain a NUL), you should not be passing it to printf with an unbounded %s format specifier.
You have two possibilities here. The first is to send the NUL character along with the data with something like:
write (fd[1], message, strlen(message) + 1);
or (probably better) use the return value from read which tells you how many bytes were read, something like:
int sz = read (fd[0], buffer, sizeof(buffer));
// should probably check sz here as well.
printf ("Message from FD[%i] : \"%*s\" .\n", fd[0], sz, buffer);

Error in _snprintf_s

I am getting this weird error with _snprintf_s:
int ival = strlen("F(LL)L");
char buff[32];
memset(buff,0,sizeof(buff));
_snprintf_s(buff,strlen("F(LL)L"),_TRUNCATE,"%s","F(LL)L");
In buff only "F(LL)" is copied even though the string length is computed as 6.
in case I specify the length parameter as strlen("F(LL)L") + 1 complete string is copied.
The second argument to _snprintf_s() is the size of the target buffer (in bytes). One byte has to be reserved for the terminating NUL character, that's why the last character of your input string is not copied.
It would be better (and much safer) to pass the actual size of the buffer instead of the length of the input string:
_snprintf_s(buff, sizeof(buff), _TRUNCATE, "%s", "F(LL)L");