Solved

Formatted string input and output with cout

Posted on 2004-09-21
6
517 Views
Last Modified: 2010-04-01
I'm having an issue trying to format a char * using cout, so that I get the same result as with the printf example below:

    char *str = "David";

    printf ("%.4s\n", str);

this will print "Davi", but I'd like to do the same thing with cout. cout.width(4) or setw(4) work well with numbers but not with strings. Is there some other function or manipulator that does this? This seems like it should be very easy to do, but online help and MSDN has provided no insight that I could find. An example using formatted input for scanf (like using istrstream) would be useful as well. Thanks.
0
Comment
Question by:davev
  • 3
  • 2
6 Comments
 
LVL 9

Accepted Solution

by:
jhshukla earned 50 total points
ID: 12113223
char *str = "David" is UNSAFE!! do not do this. use new() instead
char *str = new char[strlen("David")+1];
strcpy(str, "David");
str[strlen("David")] = 0;

don't forget delete[] str;

or better version
char str[] = "David";

I did not hardcode the value of strlen because this could be in a function and str would need to get a copy of the original string.

=====

if you are willing to use stl string then your job is easy
string str = "David";
cout << str.substr(0,4) << endl;

if you cannot or do not want to use stl then you will have to write a substring function. unfortunately it is not included in the cstring library. but the good part is that it's trivial and easy to write.
then create a string as described above and do
cout << substr(str,0,4) << endl;

post comments if you need more help

jaydutt
0
 
LVL 17

Expert Comment

by:rstaveley
ID: 12122267
You've found by now, no doubt that the manipulator setw(4) sets the minimum width only and doesn't truncate the string.

jaydutt is right about using substr, but wrong about:

>char *str = "David" is UNSAFE!! do not do this. use new() instead
>char *str = new char[strlen("David")+1];

You should write:

const char *str = "David";

It was a compromise for C portability that a non-const char pointer is permitted to read-only memory in C++. I'd actually prefer it, if the compiler issued a warning about the assignment...

 char *str = "David";

Maybe some compilers do.

The const char* could not be used for something which gets '\0' poked into it (e.g. strtok), and couldn't therefore be used for a substr function which pokes a '\0' into the char array. The compiler will prevent you from making that mistake if you are "const-correct".
0
 

Author Comment

by:davev
ID: 12123046
Good points from the two who responded so far and I will take what was said into consideration. I had thought of using a substr type of approach, but I'd still like to find ways for cout or any of the other ostream classes to support *all* the formatter a function like printf such that a conversion from printf (":%5.4s:", str) will still produce ": Davi:" when used with cout. Any other feedback is greatly appreciated. Thanks.
0
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).

 
LVL 9

Expert Comment

by:jhshukla
ID: 12129363
write a function yourself!
string foo(const string format_string, const string print_string) should parse the format_string and insert appropriate contents from print_string in to the result. then you could use it like cout << foo("%5.4", str);

or the long way would be to derive a class from ostream and add ~10-20 of member variables and overload some functions from the ostream.
0
 
LVL 9

Expert Comment

by:jhshukla
ID: 12233513
I think you can do %3.7 with strings using sprintf. I saw it somewhere in one of these rooms.
0
 
LVL 17

Expert Comment

by:rstaveley
ID: 12235138
By all means use sprintf - see http://www.cplusplus.com/ref/cstdio/sprintf.html but include <cstdio> header rather than <stdio.h>.

Unlike printf/fprintf, there is no reason not to mix sprintf with C++ IOStreams other than philosophical. It is much better if you can embrace the design philosophy of C++ to get comfortable with it. sprintf leaves you with thoughts like "How big should I make that buffer?"/"If I have a great big buiffer on the stack, how should I return a string?" etc. None of these questions are rocket science to resolve, but there's something ugly about (say) seeing sprintf formatting a buffer provided by std::vector<char>.
0

Featured Post

Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

Join & Write a Comment

Article by: SunnyDark
This article's goal is to present you with an easy to use XML wrapper for C++ and also present some interesting techniques that you might use with MS C++. The reason I built this class is to ease the pain of using XML files with C++, since there is…
Templates For Beginners Or How To Encourage The Compiler To Work For You Introduction This tutorial is targeted at the reader who is, perhaps, familiar with the basics of C++ but would prefer a little slower introduction to the more ad…
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.

757 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

21 Experts available now in Live!

Get 1:1 Help Now