Formatted string input and output with cout

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.
Who is Participating?
jhshuklaConnect With a Mentor Commented:
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

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".
davevAuthor Commented:
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.
The 14th Annual Expert Award Winners

The results are in! Meet the top members of our 2017 Expert Awards. Congratulations to all who qualified!

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.
I think you can do %3.7 with strings using sprintf. I saw it somewhere in one of these rooms.
By all means use sprintf - see 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>.
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.