7

I've been trying to look for answer myself, but I can't find one. I want to insert a part of the programming that reads in a string like "Hello" and stores and can display it when I want, so that printf("%s", blah); produces Hello.

Here's the code part that's giving me trouble

char name[64];
scanf_s("%s", name);
printf("Your name is %s", name);

I know that printf isn't the problem; the program crashes after something is input after a prompt. Please help?

5
  • 9
    The 'secure' version of scanf requires that you supply the length of the buffer. Commented Apr 30, 2014 at 2:27
  • 4
    Just use scanf(), instead of this scanf_s(). Or, even better, fgets(). Commented Apr 30, 2014 at 2:27
  • 1
    Do you have a stack trace for the same? If yes please post it. Commented Apr 30, 2014 at 2:40
  • If using scanf you must specify the length to avoid a buffer overflow: scanf("%63s", name); Commented Apr 30, 2014 at 3:44
  • This worked for me: stackoverflow.com/a/17067317/830514, I am using VS 2013, C program. Commented Mar 19, 2015 at 22:10

7 Answers 7

7

From the specification of fscanf_s() in Annex K.3.5.3.2 of the ISO/IEC 9899:2011 standard:

The fscanf_s function is equivalent to fscanf except that the c, s, and [ conversion specifiers apply to a pair of arguments (unless assignment suppression is indicated by a *). The first of these arguments is the same as for fscanf. That argument is immediately followed in the argument list by the second argument, which has type rsize_t and gives the number of elements in the array pointed to by the first argument of the pair. If the first argument points to a scalar object, it is considered to be an array of one element.

and:

The scanf_s function is equivalent to fscanf_s with the argument stdin interposed before the arguments to scanf_s.

MSDN says similar things (scanf_s() and fscanf_s()).

Your code doesn't provide the length argument, so some other number is used. It isn't determinate what value it finds, so you get eccentric behaviour from the code. You need something more like this, where the newline helps ensure that the output is actually seen.

char name[64];
if (scanf_s("%s", name, sizeof(name)) == 1)
    printf("Your name is %s\n", name);
Sign up to request clarification or add additional context in comments.

2 Comments

Shouldn't the third argument of scanf_s be cast to (unsigned int) as sizeof returns a value of type size_t?
@CoolGuy: If you're going to cast it, it should be cast to rsize_t (see the quote in the answer), but K.3.3 Common definitions <stddef.h> says (in its entirety): The header <stddef.h> defines a type.The type is rsize_t which is the type size_t. and references footnote 385, which says: See the description of the RSIZE_MAX macro in <stdint.h>. The discussion of RSIZE_MAX is considerably more extensive, but the intent is that it should usually be smaller than SIZE_MAX, with SIZE_MAX >> 1 being a suggested size.
5

I used this very often in my university classes so this should work fine in Visual Studio (tested in VS2013):

char name[64]; // the null-terminated string to be read
scanf_s("%63s", name, 64);
// 63 = the max number of symbols EXCLUDING '\0'
// 64 = the size of the string; you can also use _countof(name) instead of that number
// calling scanf_s() that way will read up to 63 symbols (even if you write more) from the console and it will automatically set name[63] = '\0'
// if the number of the actually read symbols is < 63 then '\0' will be stored in the next free position in the string
// Please note that unlike gets(), scanf() stops reading when it reaches ' ' (interval, spacebar key) not just newline terminator (the enter key)
// Also consider calling "fflush(stdin);" before the (eventual) next scanf()

Ref: https://msdn.microsoft.com/en-us/library/w40768et.aspx

Comments

0

Here is a part of code that works for me fine:

char name[64];
scanf_s("%63s", name,(unsigned)_countof(name));
printf("Your name is %s", name);

For more information here is a link: https://learn.microsoft.com/de-de/cpp/c-runtime-library/reference/scanf-s-scanf-s-l-wscanf-s-wscanf-s-l?view=msvc-170

Best Regards

1 Comment

That does not look portable though.
0

The scanf_s function is equivalent to scanf except that %c, %s, and %[ conversion specifiers each expect two arguments (the usual pointer and a value of type rsize_t indicating the size of the receiving array, which may be 1 when reading with a %c into a single char)

Your code doesn't provide the size of receiving array, also the variable name is a pointer pointing to the first character of the array, so it contains the address of name[0]. Therefore your first argument name in scanf_s is correct because name is a pointer, also note that, for the second argument you can't insert the size of a pointer like sizeof(name) because it is always same. You need to specify the size of your char array (name[64]), so for the second argument you should insert sizeof(name) or sizeof(char[64]) or 64*sizeof(char).

You can correct your code as follows:

char name[64];
if (scanf_s("%s", name, sizeof(name)) == 1)
    printf("Your name is %s\n", name);

1 Comment

sizeof(name[64]) should be sizeof(name)
-1

you should do this : scanf ("%63s", name);

Update:

The below code worked for me:

#include <stdio.h> 
int main(void) { 
    char name[64]; 
    scanf ("%63s", name); 
    printf("Your name is %s", name); 
    return 0; 
}

if you are using visual studio, go to Project properties -> Configuration Properties -> C/C++-> Preprocessor -> Preprocessor Definitions click on edit and add _CRT_SECURE_NO_WARNINGS click ok, apply the settings and run again.

Note: this is only good if you are doing your homework or something like that and it's not recommended for production.

6 Comments

Still didn't work, it doesn't crash anymore, but the printf won't show the result.
I tried this and it worked, #include <stdio.h> int main(void) { char name[64]; scanf ("%63s", name); printf("Your name is %s", name); return 0; }
I'm using Visual Studio and it won't let me use scanf, just scanf_s, but even with the buffer, it won't work, just skips the %s in the printf afterwards.
you started a visual c++ project?
go to Project properties->Configuration Properties->C/C++->Preprocessor->Preprocessor Definitions click on edit and add _CRT_SECURE_NO_WARNINGS click ok, apply the settings and run the project
|
-2
    #include<stdio.h>

    int main()
    {
      char name[64];

      printf("Enter your name: ");
      scanf("%s", name);
      printf("Your name is %s\n", name);

     return 0;
    }

11 Comments

isn't it : scanf("%s", name); (no '&')?
'&' is not required here. The array name itself will give the address of the array.
The & on &name does no harm, but is not needed. Leave it off because you understand the relationship between arrays and pointers. If you don't understand that relationship go read about it and then leave the extra & off.
Hmmm ... may be wrong about the pointer conversion. In which case a hypothetical compiler that stores pointers to arrays differently than other pointers could conceivably show different behavior.
@dmckee: The notation &name generates a char (*)[64] in the context of the question (char name[64];). The %s format expects a char *, and simply referencing name yields a char *. As you can see, the two types are quite radically different. The unfortunate curiosity is that the value of &name viewed as a void * is the same as the value of name viewed as a void *. This allows scanf("%63s", &name) to 'work', but doesn't stop it being incorrect.
|
-3
#include<stdio.h>

int main()
{
  char name[64];
  printf("Enter your name: ");
  gets(name);
  printf("Your name is %s\n", name);
 return 0;
}

2 Comments

Welcome to Stack Overflow! While this code may answer the question, providing additional context regarding how and/or why it solves the problem would improve the answer's long-term value. It also doesn't hurt to mention why this answer is more appropriate than others.
Ah, yes. A code snippet with no context and doesn't answer the question. Brilliant.

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.