Solved

simple beginners question for 50 points

Posted on 2002-04-11
31
243 Views
Last Modified: 2010-04-02
Hi, just coming from java and trying to learn c++ now. Now I have a problem, I didn't think it could be a problem, because it looks so simple (and in java, it is simple ;)...

i have:

int n = 5;
char * s = "the value of n is: ";

how can i make one string out of these two values:

"the value of n is: 5"

so:
- how to make a string representation of a number ?
- how to concat two strings ?

thanks a lot!

0
Comment
Question by:benutzername
  • 11
  • 9
  • 6
  • +2
31 Comments
 
LVL 4

Expert Comment

by:pagladasu
ID: 6934354
char *s = new char[256]; //aloocate memory
int n = 5;
sprintf(s,"the value of n is:%d",n);
cout << s;

how to make a string representation of a number :
look at itoa() function

how to concat two strings
look at strcat() function
0
 
LVL 86

Accepted Solution

by:
jkr earned 50 total points
ID: 6934357
The C solution:

#include <stdio.h>
char acString [ 255];

int n = 5;
char * s = "the value of n is: ";

sprintf ( acString, "%s%d", acString, n);

printf ( acString);

The C++ solution:

#include <iostream>
#include <sstream>
using namespace std;

stringstream ss;

int n = 5;
char * s = "the value of n is: ";

ss << s << n;

cout << ss.str();

PS: Interessantes User-Kürzel :o)
0
 
LVL 1

Expert Comment

by:Pavlik
ID: 6934377
#include <string>
#include <sstream>

void f()
{
  int n = 5;
  char * s = "the value of n is: ";

  std::stringstream stream;
  stream << s << n;

  std::string str = stream.str();
}
=====================================

After this code you will have result string in str.

> - how to make a string representation of a number ?
create std::stringstream and serialize this number to it.

> - how to concat two strings ?
If you have 2 objects of std::string (s1 and s2 for example) then concatenation will be s1 + s2


But you definitely should read Stroustrup's 3rd edition.
0
 
LVL 1

Expert Comment

by:Pavlik
ID: 6934394
GUYS!!!!!!!


Let's STOP using DANGEROUS function sprintf().

If only you what huge amount of bugs i've seen related to usage of this function.

You can at least use snprintf instead. (_snprintf in windows).

And by the way in c++ you can use streams, that are much more type safe then all the family of printf/scanf.
0
 

Author Comment

by:benutzername
ID: 6934527
Thanks for the fast support, guys :))))

Pavlik, you told me, sprintf() is dangerous - what does that mean ? What can happen ? ("unsafe" is a rarely heard word for a Java programmer ;)

If using streams is safer, I still have a problem: I will have to convert the string back into char.

Detail:
I'm using SDL (simple device layer) for graphics programming. SDL has a method called SDL_LoadBMP(const char *filename). If I give it a string instead, it won't work.

So what I have to do is:

char * prefix = "image";
char * suffix = ".bmp";
int n = 5;

now I want to load image number 5:

char * filename = /* working solution */
LoadBitmap(filename);

0
 
LVL 86

Expert Comment

by:jkr
ID: 6934539
Well, in this case:

include <iostream>
#include <sstream>
using namespace std;

stringstream ss;


char * prefix = "image";
char * suffix = ".bmp";
int n = 5;

ss << prefix << n << suffix;

char * filename = ss.str().c_str(); // "image5.bmp"
LoadBitmap(filename);
0
 

Author Comment

by:benutzername
ID: 6934552
Thanks for the fast support, guys :))))

Pavlik, you told me, sprintf() is dangerous - what does that mean ? What can happen ? ("unsafe" is a rarely heard word for a Java programmer ;)

If using streams is safer, I still have a problem: I will have to convert the string back into char.

Detail:
I'm using SDL (simple device layer) for graphics programming. SDL has a method called SDL_LoadBMP(const char *filename). If I give it a string instead, it won't work.

So what I have to do is:

char * prefix = "image";
char * suffix = ".bmp";
int n = 5;

now I want to load image number 5:

char * filename = /* working solution */
LoadBitmap(filename);

0
 

Author Comment

by:benutzername
ID: 6934556
ooops.. it wasn't me, it was the reload button ;)
0
 
LVL 30

Expert Comment

by:Axter
ID: 6934557
>>You can at least use snprintf instead. (_snprintf in
>>windows).

_snprintf is not a portable function, and I wouldn't recommend using it.

snprintf is part of the C standards, but it's not part of the C++ standard.

While using sprintf is not type safe, you still should not completely rule it out for code use.
As usual, there isn't a one size fits all with stream methods.
If performance is an issue, you'll usually want to use sprintf VS stringstream or (printf family) VS (std::stream family).
Also many programmers prefer the readability of a printf family functions over the std::streams.

I, myself, prefer to use the sprintf function when posting example code, because I want the questioner to be able to focus on the part of the code that answers the main question, rather then have to look at a bunch of extra code that has nothing to do with the original question.
0
 

Author Comment

by:benutzername
ID: 6934568
hmm... doesn't work:

line 17: char * filename = ss.str().c_str();

E:\CPP\test_7_console\Main.cpp(17) : error C2440: 'initializing' : cannot convert from 'const char *' to 'char *'
        Conversion loses qualifiers
0
 
LVL 86

Expert Comment

by:jkr
ID: 6934573
>>rather then have to look at a bunch of extra code that
>>has nothing to do with the original question.

Is that the same Axter who once posted "I like to give advanced examples"? :o)
0
 
LVL 30

Expert Comment

by:Axter
ID: 6934576
>>line 17: char * filename = ss.str().c_str();

Make it a constant.
Example:

const char * filename = ss.str().c_str(); // "image5.bmp"
0
 
LVL 86

Expert Comment

by:jkr
ID: 6934578
Make it either read

const char * filename = ss.str().c_str();

or

char * filename = conat_cast<char*> (ss.str().c_str());

or

char * filename = ( char*) ss.str().c_str();


0
 
LVL 30

Expert Comment

by:Axter
ID: 6934579
>>Is that the same Axter who once posted "I like to give
>>advanced examples"? :o)

I do like to give advance examples, but I dont' want to be nagged when I don't.
0
 
LVL 30

Expert Comment

by:Axter
ID: 6934582
jkr,
The last two methods you posted could be dangerous.
char * filename = conat_cast<char*> (ss.str().c_str());
char * filename = ( char*) ss.str().c_str();

Because a string object can change it's pointer at any time, and delete it's old pointer.

filename would then be pointed to a deleted string, which would result in undefined behavior.
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 

Author Comment

by:benutzername
ID: 6934587
>>Make it a constant.
Ok, that works. But: I want to load about 10.000 Bitmaps - if I'm using a constant char, than I always have to delete and reconstruct it (because it's constant). Is that right ? Wouldn't be very efficient in that case...(?true?)

sprintf(..) works fine. What is unsafe about it ?


besides:

Where do I find information about the usage of all these methods you are writing about ? Is there a standard-api-documentation like in java ? I have the MSDN documentation, but I still have my problems, finding the way through this huge and hard to read document...

Any tips for good VC++ documentation ? I don't need something like "Learning VC++" but more like an encyclopedia...
0
 
LVL 30

Expert Comment

by:Axter
ID: 6934591
Come to think of it, this applies to a const char* too.

Example:
#include <iostream>
#include <string>

using namespace std;


int main(int argc, char* argv[])
{
     std::string foo = "Hello";
     const char* foo_ptr = foo.c_str();
     foo = "Some really big long string *******";
     foo +=foo+foo+foo+foo;

     cout << "foo = " << foo << endl;
     cout << "foo_ptr = " << foo_ptr << endl;

     system("puase");
     return 0;
}
 
0
 

Author Comment

by:benutzername
ID: 6934592
I'm using

     char *s = new char[256]; //aloocate memory
     int n = 5;
     sprintf(s,"image%d.bmp",n);

now, for reasons of simplicity. Is that code safe ?
0
 
LVL 1

Expert Comment

by:Pavlik
ID: 6934595
The reason why i am against sprintf is that it helps hackers a lot.
Consider function:

void f(char* szStr)
{
  char buf[256];
  sprintf(buf, "parameter is %s", szStr);
}

(I know this looks wrong but believe me i've seen such code a lot)

What will happen when i pass 256 bytes long string to szStr?
Right! It will overwrite the stack. And do you know where your new IP value will point to? Good hacker can make it to point to the code he passed in the same string. And can you imagine what this hacker can do having 256 bytes of code executing on your box? For example load another 50Kb of code and run it. After that your box isn't yours anymore.
0
 
LVL 30

Expert Comment

by:Axter
ID: 6934603
The point of the above code, is that you should never store a pointer to an std::string or stringstream.
This can cause all kinds of problems.
If the string or stringstream object goes out of scope, you'll again end up with a pointer to a deleted string.

If you need to safe the information in the object, safe it to another std::string instead.
Example:
std::string filename = ss.str().c_str();
LoadBitmap(filename.c_str());

0
 
LVL 30

Expert Comment

by:Axter
ID: 6934615
>>now, for reasons of simplicity. Is that code safe ?
Safer would be if you didn't create the string using new.

char s[256]; //Don't use new
int n = 5;
sprintf(s,"image%d.bmp",n);

If you did it this way, you don't have to worry about deleteing the string later.
0
 

Author Comment

by:benutzername
ID: 6934634
So pointers to strings only become unsafe, when I exceed the original length of the string ? Otherwise C++ won't have a reason for changing the address of the string - is that true ?

Pavlik: The hackers won't be a problem, as long as I'm not writing network software - true ?
...for network software I could simply close the security hole by checking the length of the parameter.

0
 
LVL 1

Expert Comment

by:Pavlik
ID: 6934639
About using c_str() member:

(from the C++ standart)
The program shall not treat the returned value as a valid pointer after any subsequent call to a non-const member function of the same object (string).

So you can use pointer returned from c_str() as long as you don't modify this string.
0
 
LVL 30

Expert Comment

by:Axter
ID: 6934663
>>So you can use pointer returned from c_str() as long as
>>you don't modify this string.
And as long as the string does not go out of scope.
0
 
LVL 1

Expert Comment

by:Pavlik
ID: 6934673
> The hackers won't be a problem, as long as I'm not writing network software - true ?
...for network software I could simply close the security hole by checking the length of the parameter

You are wrong. Microsoft event viewer don't have anything to do with network at all. But some hacker hacked network related program runing under user privilegies and made it to write event to event log containing hacker's code. And event was formatted in the way that it caused the problem with stack overwrite in the event viewer. And when admin of this box opened that event this hacker's code was run UNDER ADMINISTRATOR PRIVILEGIES!!!!!

There was interesting problem related to soft links in Linux that allowed to elevate privilegies for almost guest user to admin level.
0
 
LVL 30

Expert Comment

by:Axter
ID: 6934692
>>So pointers to strings only become unsafe, when I exceed
>>the original length of the string ? Otherwise
>>C++ won't have a reason for changing the address of the
>>string - is that true ?
This is not entirely true.
The standard allows for implementation to use refferncing.  That means you could have two string objects pointing to the same buffer.
Example:
std::string Str1 = "Foo Foo";
std::string Str2 = Str1;
const char *FooFoo = Str2.c_str();
Str2 = "Not Foo";

With the above code, Str2 can actually be pointing to Str1 data at first.
But when you modify Str2, Str2 will then stop pointing to Str1, and create it's own buffer that will store the new string.

Now your FooFoo pointer is pointing to data in Str1, instead of data in Str2, and if Str1 goes out of focus, you'll be pointing to deleted data.

There are too many things that can go wrong when pointing to an std::string data pointer, so I highly recommend, never to store a pointer to a std::string object.
Use it, but don't store it.
0
 
LVL 30

Expert Comment

by:Axter
ID: 6934752
Here's a running example of using a pointer and changing reference.

int main(int argc, char* argv[])
{
     std::string FooFoo = "Foo Foo";
     std::string NotFoo = FooFoo;
     const char *NotFoo_ptr = NotFoo.c_str();
     NotFoo = "Not Foo";
     cout << "FooFoo = " << FooFoo << endl;
     cout << "NotFoo = " << NotFoo << endl;
     cout << "NotFoo_ptr = " << NotFoo_ptr << endl;

     return 0;
}

The above code will have the following output in VC 6.0

FooFoo = Foo Foo
NotFoo = Not Foo
NotFoo_ptr = Foo Foo

As you can see, NotFoo_ptr ends up pointing to FooFoo, instead of pointing to NotFoo.

Not all implementations use referencing, but most do.

This is just one of the many unexpected problems you can come accross when storing a pointer to a std::string object.
So I recommend you don't do it.  Just call on the object's c_str() member function when ever you need to access the data.  It's much safer.
0
 

Author Comment

by:benutzername
ID: 6934767
Pavlik: Wow! That says, as long as i run any software on my computer, that was made by someone who didn't know/care about this security hole, someone could hack my computer through this hole ? I have so many programs running, it would be a wonder if i didn't have any holes...

Does a firewall help against this risk ? I'm using a router (1st firewall, ip masking) and ZoneAlarm (2nd firewall, programs need privileges to acces internet)

0
 

Author Comment

by:benutzername
ID: 6934779
thanks a lot, guys - who will get the points now ?
0
 
LVL 1

Expert Comment

by:Pavlik
ID: 6934804
benutzername:
Assume that every softvare has security holes. The more software you have running, the more chances you can be hacked. And there is no unified way to protect from all possible attacks.
So my point is: shut down all the software you don't use. Check for software updates. Don't have resources which would be interesting for hacker.
If you happen to have some important resources (for example information or access to some private network) think about ways how you box can be hacked and protect it.

About points: i don't need it. If i were i would post my message as an answer.
0
 
LVL 30

Expert Comment

by:Axter
ID: 6934818
IMHO, pagladasu and jkr answered your original question.

Although pagladasu, answered the question first, jkr gave you two methods with better implementation.
0

Featured Post

Top 6 Sources for Identifying Threat Actor TTPs

Understanding your enemy is essential. These six sources will help you identify the most popular threat actor tactics, techniques, and procedures (TTPs).

Join & Write a Comment

Suggested Solutions

Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
Basic understanding on "OO- Object Orientation" is needed for designing a logical solution to solve a problem. Basic OOAD is a prerequisite for a coder to ensure that they follow the basic design of OO. This would help developers to understand the b…
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.

708 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now