-2

I have run following C code in the Code::Blocks IDE and it worked properly without a problem. I tried compiling this code in Visual Studio 2015, and I got this error:

'strcpy_s': too few arguments for call

How can I fix this with minimal changes to my code? Here's the code:

#include<conio.h>
#include<stdio.h>
#include<string.h>
int main() {
    char string[81];
    int position;
    printf("type a string :");
    gets(string);
    printf("enter position for delete character :");
    scanf_s("%d",&position);
    strcpy_s(&string[position], &string[position + 1]);
    printf("the result string is: ");
    puts(string);
    _getch();
    return 0;
}

Code::Clocks can run this code and gives me the correct output, but Visual Studio does not! What can I do?

Marco Bonelli
  • 55,971
  • 20
  • 106
  • 115
  • 2
    Two points about `gets()` a) if you mix its use with `scanfX()` functions it is likely you will have problems, and b) please read [Why is the gets function so dangerous that it should not be used?](https://stackoverflow.com/questions/1694036/why-is-the-gets-function-so-dangerous-that-it-should-not-be-used) It is obsolete. – Weather Vane Oct 26 '20 at 17:30
  • thank to @WeatherVane ,thats work – Mohammad Razmjoo Oct 26 '20 at 17:58

1 Answers1

2

You are using strcpy_s, which is a specialized version of strcpy that does additional error checking and wants exactly 3 arguments:

errno_t strcpy_s(char *dest, rsize_t dest_size, const char *src);

I suppose you don't really need this. Use the standard strcpy function instead:

strcpy(&string[position], &string[position + 1]);

NOTE: same goes for scanf_s, use scanf instead if you don't have a good reason why scanf_s might be more useful to you.

As per why Code::Blocks compiles your code, well, it's probably just generating a warning instead of an error that aborts compilation.


Okay, turns out MSVC is particularly pedantic about this and doesn't like good ol' (faster and simpler) standard functions.

I changed to strcpy but Visual studio gives me this error now: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.

You have two options:

  1. Disable the check, see this related question and answer: How to use _CRT_SECURE_NO_WARNINGS.

    Basically just add this at the very top of your file (before any #include):

    #define _CRT_SECURE_NO_WARNINGS
    
  2. Use strcpy_s in the proper way (also, check that position < strlen(string) first, otherwise your replacement is invalid):

    strcpy(&string[position], 81 - position, &string[position + 1]);
    

    And don't forget to check the return value!


Finally, while we are at it, using gets(string) is ALWAYS wrong. Never use gets(). Really surprised MSVC does not warn you about this. Use fgets instead:

fgets(string, 81, stdin);
Marco Bonelli
  • 55,971
  • 20
  • 106
  • 115
  • It is [standard now](https://en.cppreference.com/w/c/string/byte/strcpy), +1 anyway – Jabberwocky Oct 26 '20 at 17:23
  • @Jabberwocky thank you, I wrongly assumed it was some Windows specific function. – Marco Bonelli Oct 26 '20 at 17:24
  • if i do what u say visual studio does not accept and give me this error: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. – Mohammad Razmjoo Oct 26 '20 at 17:28
  • and about scanf this error : 'scanf': This function or variable may be unsafe. Consider using scanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. actualy in code::blocks I typed strcpy and scanf ,not strcpy_s and scanf_s – Mohammad Razmjoo Oct 26 '20 at 17:31
  • @MarcoBonelli thanks alot men. very helpful. but without [ #define _CRT_SECURE_NO_WARNINGS], I receive this error: '-': pointer can only be subtracted from another pointer. So I must edit your answer like this: strcpy_s(&string[position], 81 - (position - string[81]), &string[position + 1]); – Mohammad Razmjoo Oct 26 '20 at 18:04
  • @MohammadRazmjoo whoops, my bad, fixed. – Marco Bonelli Oct 26 '20 at 18:06
  • @MarcoBonelli your edit is cool again, and about gets(string), I remember it ! – Mohammad Razmjoo Oct 26 '20 at 18:13
  • One note: In C++ there are templates defined that make ``strcpy_s`` work with just 2 arguments where it can deduce the proper bound of the target string, so if you are coding in C looking at C++ examples that might be a source of confusion: ``char buff[128]; strcpy_s(buff, "Test");`` builds in C++ but not in C. – Chuck Walbourn Oct 27 '20 at 02:57
  • @ChuckWalbourn oh, that's pretty interesting. – Marco Bonelli Oct 27 '20 at 03:01