2

This is what i have try:

printf("Please venter first string\n");
char str[127];
scanf_s("%s", &str);

And got this exception:

Exception thrown at 0x0FD2C700 (ucrtbased.dll) in strcmp.exe: 0xC0000005: Access violation writing location 0x00500000.

I also try this:

printf("Please venter first string\n");
char str[127];
scanf_s("%d", &str);

In this case no exception but i got long and strange string.

10
  • 6
    scanf_s("%s", &str) --> scanf_s("%s", str, sizeof(str)) Commented Oct 27, 2017 at 19:09
  • @BLUEPIXY the s of scanf_s means "safe"... well, you still have to check the warnings... Commented Oct 27, 2017 at 19:12
  • @Jean-FrançoisFabre what warning? Commented Oct 27, 2017 at 19:12
  • 1
    @Jean-FrançoisFabre I quite agree, it is even more difficult to get right than scanf - which already has a length restriction feature. Commented Oct 27, 2017 at 19:16
  • 1
    "How to get string from input in C language"? --> fgets(str, sizeof str, stdin); for happy programming life. scanf_s and scanf leads down the road to perdition. Commented Oct 27, 2017 at 19:26

1 Answer 1

9

Let's start by considering the use of the standard scanf. If you write

scanf("%s", &str);

that will be incorrect (although it might work). When passing an array to a function it decays to a pointer to the first element, which is what scanf requires, so the line should be

scanf("%s", str);

If you want to restrict the input length to prevent buffer overflow it can be like this (one less than the array length to allow for the nul terminator)

scanf("%126s", str);

The allegedly safer function scanf_s requires an additional size argument to be passed for each format type %c and %s and %[] so the next line (after correcting the &)

scanf_s("%s", str);

lacks that argument, and the compiler should issue a warning about it. The code should be

scanf_s("%s", str, sizeof str);

but even that is inadequate. The Xscanf family of functions returns the number of values successfully entered. Since users (even myself) are notoriously bad at entering correct input (which may even be malicious) you must always check if the data was correctly entered. Such as

if(scanf_s("%s", str, sizeof str) != 1) {
    // inform user and retry etc. etc.
}

As mentioned by @chux it is better to obtain input by using fgets, and then process it by various means, such as sscanf or strtok or strsep or by more direct analysis of the string. In that case, and with sscanf, you can make multiple attempts to process the input, but with scanf you only get one chance. Note that strtok and strsep modify the string, so you would need to work with a copy if you need to make more than one attempt to decode it.


In your second example

scanf_s("%d", &str);

you got "no exception but a long and strange string", but you should have got a compiler warning:

warning C4477: 'scanf_s' : format string '%d' requires an argument of type 'int ', but variadic argument 1 has type 'char ()[127]'

Note that you did not initialise str to the "empty string" and if you go on to process what you imagine to be a good string after a faulty input, bad stuff can happen.

Sign up to request clarification or add additional context in comments.

1 Comment

&str is the address of the object, str decays to the address of the first element, which are not necessarily the same thing.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.