strcpy is being deprecated????
DanielH

I'm continuing to work on my math parser. It was running fine on my home computer compiled with VisC++ 8.0. Since I have some free time at school, I decided to work on it there. The problem is I received alot of warnings

strcpy being deprecated use strcpy_s
sprintf "" sprintf_s

So I bit the bullet and started using std::string's. I'm not too familiar with them so I need some help. How would I go about doing this with strings:

char temp[ 256 ] = "";
sprintf( temp, "The value is %d", value );

I tried this and that didn't work.

std::string temp;

temp = "The value is " + value;

HoHo

It is a problem of MSVC. strcpy is a standard function and no other compiler depricates it besides MSVC. Ignore the warnings and keep on using strcpy if you need it.

For std::string see this, especially the append member function.

gnolam

What about strncpy(), snprintf()?

ReyBrujo

I think Microsoft was deprecating the versions without lenght to prevent bugs.

Ninkazu

strcpy is being deprecated because say you have
char buffer[5];
strcpy(buffer, "Oh man I'm bigger than 4");

You'll start overwriting your code in memory. strcpy_s takes the size of the buffer and makes sure it's not overrun. It's a classical way hackers can take over a system - buffer overrun.

HoHo

strcpy_s is a winapi specific function. strncpy would do exactly the same thing and would be cross-platform.

TeamTerradactyl

ReyBrujo is correct with this: with the infamous AOL/MSN buffer exploits that happened so many years ago, they're trying to get away from functions that don't prevent buffer overruns. strncpy() will read up to, but not more than, the given number. Otherwise, you could declare a string of length 100, and if the user writes 104 or 108 bytes, then it can corrupt the stack or be used as an exploit.

I guess it's better to deprecate it to force programmers to start learning how to program "safely" :)

DanielH

HoHo

None of those deal with values in terms of int or long or ...

int value = 25;
std:string str = "";

str = "The value is " + value;

gives me 'The value is ***GARBAGE ***'

anonymous

The C++ way to format strings is to use std::stringstream:

#include <iostream>
#include <sstream>
#include <string>

int main()
{
    int value = 25;
    std::stringstream temp;
    temp << "The value is " << value;
    std::string s(temp.str());
    std::cout << s << '\n';
}

The best I can do to explain, why your example compiles, is that the compiler might see this as pointer arithmetics: The first part, the string literal, is actually seen as a constant char* (which one can assign to the string). Then you add 25 to the pointer, getting another char pointer pointing 25 chars onward in the memory. Whatever happens to be there, up to the first 0 character, is copied to the string.

Hmm, so if you don't know what you are doing, std::string can be unsafe too... :(

HoHo

To do that kind of things in C++ you use stringstream

CGamesPlay
Quote:

I think Microsoft was deprecating the versions without lenght to prevent bugs.

No, those are derecated, too.

And, as clearly stated in the warning, simply define _CRT_SECURE_NO_DEPRECATE to disable the warnings.

kentl

You can turn off those warnings in VS and go with the standard instead of Microsofts usual way of working against portability and standards.

Bob
Quote:

The C++ way to format strings is to use std::stringstream:

That, or boost::lexical_cast<> or boost::format<>.

Richard Phipps

Be careful with strncpy, in some situations it doesn't add terminating characters:
http://developer.apple.com/documentation/Darwin/Reference/Manpages/man3/strncpy.3.html

torhu

For anyone getting the deprecation warnings with msvc 8, just put this before any #includes:

#define _CRT_SECURE_NO_DEPRECATE

BAF
CGamesPlay

I appreciate BAF for reading my posts! :)

Billybob

For std::string, besides the methods already suggested, you may use:

template<typename T>
std::string to_string(const T &value)
{
  std::ostringstream ret;
  ret << value;
  return ret.str();
}

---------------------------------

std::string temp;

temp = "The value is " + to_string(value);

BAF

Wouldn't that be to_string<value_type>(value); ? Or do I not know how to use templates with functions (I've only ever used them with classes)?

Carrus85

BAF: No, that would not be to_string<value_type>(value);, as the template type can be automatically determined by the arguments of the function (now, if the return type was a template parameter that isn't mentioned in the argument list, you would need to specify it that way.)

Paul Pridham

Make your own:

1#include <stdio.h>
2 
3char* strcopy(char* dest, char* src)
4{
5 int i = 0;
6 
7 while(src<i>)
8 {
9 dest<i> = src<i>;
10 i++;
11 }
12 
13 dest<i> = 0;
14 
15 return dest;
16}
17 
18int main()
19{
20 char dest[10];
21 char src[] = "foobarbaz";
22 
23 strcopy(dest, src);
24 printf("%s\n", dest);
25
26 return 0;
27}

Kitty Cat
Quote:

Be careful with strncpy, in some situations it doesn't add terminating characters:

Wasn't there supposed to be a new function to take care of that? strlcpy or something. I'm positive I read something about that once, and it also fixed the issue of strncpy filling the rest of the destination string with null chars (a potential performance problem). I don't have it in my man pages, though..

Peter Wang

It's a OpenBSD (or *BSD) function. The glibc folks don't like it.

Carrus85
char* strcopy(char* dest, char* src)
{
  int i = 0;

  while(src<i>)
  {
    dest<i> = src<i>;
    i++;
  }

  dest<i> = 0;

  return dest;
}

Personally, I prefer this for strcpy

void strcopy(char* dest, char* src) {
      while( *dest++ = *src++ );
}

and this for strncpy

void strncopy(char* dest, char* src, size_t len) {
      size_t current = 0;
      while( *dest++ = *src++ && ++current < len );
      *dest = 0;
}

Untested, though.

Kitty Cat
Quote:

and this for strncpy
...
Untested, though.

Hello, Mr. Buffer Overflow. Nice to meet you. :)

That writes one byte past the end of the dest buffer. Perhaps something like this:

void strncopy(char* dest, char* src, size_t len)
{
      if(len)
      {
            size_t current = len-1;
            while( current-- )
                  *(dest++) = *(src++);
            *dest = 0;
      }
}

Carrus85

KC: Yeah, I should have caught that. I did state untested though :P (I should have checked len's validity, then done *(dest-1) = 0 as dest is already past the end at that point...)

Dustin Dettmer
Quote:

I think Microsoft was deprecating the versions without lenght to prevent bugs.

Maybe thats how the idea came up. But it ended up being more of a way to lock people into WINBLOWS specific code and make porting away from windows harder.

Paul Pridham
void strcopy(char* dest, char* src) {
      while( *dest++ = *src++ );
}

It's efficient, but isn't compatible with strcpy() since it doesn't return the original dest. That is all.

HoHo

Also nobody seemed to get the parameters right, it ischar* dest, const char* src :)

Paul Pridham

const is for wimps. ;)

HoHo

... and for compiler that wants to optimize as much as possible ;)

Joel Pettersson
HoHo said:

... and for compiler that wants to optimize as much as possible ;)

For the "smarter" ones, it often makes no difference.;)

ReyBrujo
Quote:

Maybe thats how the idea came up. But it ended up being more of a way to lock people into WINBLOWS specific code and make porting away from windows harder.

Actually, I would bet the amount of strn.* functions in the Linux kernel overwhelms the str[^n]+ ones. At least, that is what I would expect.

Dustin Dettmer
Quote:

For the "smarter" ones, it often makes no difference.;)

You've found smart compilers? Where? Are they less then $10000 a license? *

* This is a joke. Compilers are very far from perfect.

Carrus85
Quote:

char* dest, const char* src

Well, of course. Here, lets make it complete:

char* strcpy(char* dest, const char* src) {
   char* temp = dest;
   while( *dest++ = *src++ );
   return temp;
}

Or, better yet:

#include <algorithm>

char* strncpy(char* dest, const char* src, const size_t len) {
   std::copy(src, src+len, dest); // hooray for the STL!
   *(dest+len-1) = 0;
   return dest;
}

;D

Paul Pridham

Congratulations! You've just added 2MB to the executable. ;)

HoHo
Quote:

Congratulations! You've just added 2MB to the executable. ;)

1#include <algorithm>
2 
3char* strncpy(char* dest, const char* src, const size_t len) {
4 std::copy(src, src+len, dest); // hooray for the STL!
5 *(dest+len-1) = 0;
6 return dest;
7}
8 
9int main(){
10 char *str1=new char[10], *str2=new char[10];
11 strncpy(str2, str1, 9);
12 return 0;
13}
14 
15#g++ test.cpp
16#ls -l a.out
17-rwxr-xr-x 1 hoho users 7061 Mar 10 02:04 a.out

If in doubt, benchmark ;)

Joel Pettersson
Quote:

You've found smart compilers? Where? Are they less then $10000 a license? *

  • This is a joke. Compilers are very far from perfect.

Hence the quotes around and usage of "smarter" rather than "smart". I know all too well; my recent experiences with the way GCC reacts to and handles x87 (ye olde register-stack-based x86 FPU) inline assembly makes me feel like hand-coding all my DSP code in assembly.

Paul Pridham
-rwxrwxrwx+ 1 Administrators None   248 Mar  9 22:46 c_version.c*
-rwxr-xr-x  1 ppridham       None  7691 Mar  9 22:47 c_version.exe*
-rwxrwxrwx+ 1 Administrators None   335 Mar  9 22:47 stl_version.cpp*
-rwxr-xr-x  1 ppridham       None 41201 Mar  9 22:47 stl_version.exe*

Huh. Pretty bloated in Cygwin it seems.

ReyBrujo

Try compiling with -O2 -ffast-math -fomit-frame-pointer

HoHo

Better with -Os and maybe with -fomit-frame-pointer :)
Also a mingw und UPx compressing might be interesting.

Carrus85 version of strncpy (no optimizations, -Os):

-rwxr-xr-x 1 hoho users 6644 Mar 10 10:48 a.out
-rwxr-xr-x 1 hoho users 6604 Mar 10 10:48 a.out

libc strncpy:

-rwxr-xr-x 1 hoho users 6525 Mar 10 10:50 a.out
-rwxr-xr-x 1 hoho users 6517 Mar 10 10:50 a.out

I wondeor how it is possible that libc's strncpy creates smaller executable than the function Carrus gave

Seems to me as there isn't much difference between C and C++, not at least under Linux :)

Goalie Ca

Another silly discussion but...

string copy(src)
copy.c_str();

Jakub Wasilewski

When did A.cc become the Royal Benchmarking Society? Some of the threads have become kind of like Programmer Mythbusters :). "Is Java REALLY slower? Does STL really bloat your exes? Find out with your friendly host, HoHo, and his benchmarking machine!".

CGamesPlay

I like to think the community has just moved away from it-is-so-because-guru-says-it-is mysticism.

Dustin Dettmer

The community has grown wiser :)

Billybob
Quote:

I like to think the community has just moved away from it-is-so-because-guru-says-it-is mysticism.

Using the ++ operator makes your programs larger.

Dustin Dettmer
Quote:

Using the ++ operator makes your programs larger.

How very wise. Another little known fact is that for statements also make your programs larger!

HoHo
Quote:

I like to think the community has just moved away from it-is-so-because-guru-says-it-is mysticism.

I'd like to think that people benchmark more and guess less :)

Jakub Wasilewski, thanks for my new sig ;D

runderwo

The posted strncpy() replacement also violates the semantics of strncpy, namely that the destination buffer is padded up to the length if the source is shorter. And it's invalid if called with length 0.

There's no reason to reinvent these functions except for better portability... because doing so creates problems like this that lurk, just waiting to be exploited in released code.

Thread #590442. Printed from Allegro.cc