By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
434,985 Members | 2,877 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 434,985 IT Pros & Developers. It's quick & easy.

seeking within ostringstream's

P: n/a
What is a stringsteam supposed to do when you seek past the end of
existing buffer. I can seek past the end of a file stream (my
implementation fills the space will nulls but I cannot find if this is
guaranteed either)

Below code fails for a stringstream. Any good ways of dealing with
this.

Reason for doing this is that I am modify old C code for screen output
that positions fields based on a row. I wanted to use a stringstream
and just seek to the correct place.

I have tried basically filling the stream with X spaces first. But
then I am never sure there is enough space.

Any help appreciated.

Adrian

#include <iostream>
#include <sstream>
#include <fstream>

int main(int argc, char *argv[])
{
std::ofstream out("test.txt");

out.seekp(500);
out << "some text\n";

std::ostringstream out2;

out2.seekp(500);
out2 << "some text\n";

if(!out2)
{
std::cout << "bad out2\n";
}
return 0;
}

Sep 13 '07 #1
Share this Question
Share on Google+
7 Replies


P: n/a

Adrian <nn**@bluedreamer.comwrote in message...
What is a stringsteam supposed to do when you seek past the end of
existing buffer. I can seek past the end of a file stream (my
implementation fills the space will nulls but I cannot find if this is
guaranteed either)

Below code fails for a stringstream. Any good ways of dealing with
this.

Reason for doing this is that I am modify old C code for screen output
that positions fields based on a row. I wanted to use a stringstream
and just seek to the correct place.

I have tried basically filling the stream with X spaces first. But
then I am never sure there is enough space.

Any help appreciated.
Adrian

#include <iostream>
#include <sstream>
#include <fstream>

int main(int argc, char *argv[]){
std::ofstream out("test.txt");

out.seekp(500);
out << "some text\n";

std::ostringstream out2;

out2.seekp(500);
if( not out2 ){
std::cout << "out2 in failure\n";
}
else{
std::cout << "out2 position=" <<out2.tellp()<<'\n';
}
out2 << "some text\n";

if(!out2)
{
std::cout << "bad out2\n";
}
return 0;
}
Your result?

--
Bob R
POVrookie
Sep 13 '07 #2

P: n/a
On Sep 13, 12:40 pm, "BobR" <removeBadB...@worldnet.att.netwrote:
Below code fails for a stringstream. Any good ways of dealing with
this.
Your result?
The stringstream is not in a good state. I tried it with exceptions on
and I get
"basic_ios::clear" from what()
Sep 13 '07 #3

P: n/a

Adrian <nn**@bluedreamer.comwrote in message...
On Sep 13, 12:40 pm, "BobR" wrote:
Below code fails for a stringstream. Any good ways of dealing with
this.
Your result?

The stringstream is not in a good state. I tried it with exceptions on
and I get
"basic_ios::clear" from what()
I think a safer way to move to a position might be:

std::ostringstream out2;
// ....

size_t pos( out2.tellp() );
std::string Space( ( 500 - pos ), ' ' );

// out2.seekp(500);
out2<<Space;

// ....

--
Bob R
POVrookie
Sep 13 '07 #4

P: n/a
On Sep 13, 7:05 pm, Adrian <n...@bluedreamer.comwrote:
What is a stringsteam supposed to do when you seek past the end of
existing buffer. I can seek past the end of a file stream (my
implementation fills the space will nulls but I cannot find if this is
guaranteed either)
I can't find anything really specifying it either, but I suspect
that it's undefined behavior (or unspecified). It also depends
on whether you are using the two argument form of seek, or the
one argument form. (With the one argument form, it's actually
impossible to obtain a position which you haven't already
visited without involving undefined or unspecified behavior.
With the possible exception of start of file.)

Logically, one might say that a good implementation would
generate an error on an attempt to seek beyond end of file, but
in practice, this would have significant run-time cost on some
systems.
Below code fails for a stringstream. Any good ways of dealing with
this.
Reason for doing this is that I am modify old C code for
screen output that positions fields based on a row. I wanted
to use a stringstream and just seek to the correct place.
I have tried basically filling the stream with X spaces first.
But then I am never sure there is enough space.
#include <iostream>
#include <sstream>
#include <fstream>
int main(int argc, char *argv[])
{
std::ofstream out("test.txt");
out.seekp(500);
The above line is not even guaranteed to compile, much less do
anything useful.
out << "some text\n";
std::ostringstream out2;
out2.seekp(500);
And the same holds true here.
out2 << "some text\n";
if(!out2)
{
std::cout << "bad out2\n";
}
return 0;
}
I'm not too sure what you're doing, but it sounds like what you
want is something like std::string or std::vector<char>, using
resize( ' ' ) as needed.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Sep 14 '07 #5

P: n/a
On Sep 14, 3:34 am, James Kanze <james.ka...@gmail.comwrote:
I'm not too sure what you're doing, but it sounds like what you
want is something like std::string or std::vector<char>, using
resize( ' ' ) as needed.
I am trying to clean up and rewrite some old code that is creating
rows for screen display that uses cursor position and printf type
args.

Thing is I can never tell exactly how long the row could be. And the
version of snprintf on this platform returns -1 if printed string is
longer then buffer rather then what should be then length.

I was hoping with seeking in a stringstream I could keep almost the
same arguments

Example of old stuff below:
pn1(0, row, "%-10s", HemName_of(obj));
pn1(11, row, "%-2s",
Area_sh_nms[Mt_AreaFromCnum(Mt_Cnum_of(obj))]);
pn1(14, row, "%-8d", Mt_Cnum_of(obj));
pn1(23, row, "%-6s", Mt_ObjTypeName_of(obj));
pn1(30, row, "%-7s", Mt_CmdtyName_of(obj));
if (Mt_ObjType_of(obj) == EQUITY_TYPE)
pn1(38, row, "%-25s", Mt_Name_of(obj));
else {
strcpy(XSymb, Mt_Name_of(obj));
if (strlen(XSymb) 14) {
XSymb[14] = '*';
XSymb[15] = '\0';
}
pn1(38, row, "%-15s", XSymb);
}
if (Mt_ObjType_of(obj) == FUTURE_TYPE)
{
pn1(54, row, "%-.6ld", Mt_dtoymd(Mt_ExpDate_of(obj)));
pn1(62, row, "%-6s",
HemName_of(Mt_FindByLdOptIndx(Mt_RelLdOpt_of(obj)) ));
}
else if (Mt_ObjType_of(obj) == BOND_TYPE)
{
pn1(54, row, "%-.6ld", Mt_dtoymd(Mt_ExpDate_of(obj)));
pn1(62, row, "%-6s", Mt_SymAlias_of(obj));
}
if (((Mt_ObjType_of(obj) == FX_TYPE) ||
(Mt_ObjType_of(obj) == CASH_VOL_TYPE))
&& (Mt_HeFlags_of(Mt_Cmdty_of(obj)) & CASH_SCALE_MSK))
{
pn1(69, row, "%-7s", Display_scale_of(Mt_CshScale_of(obj)));
}
else
pn1(69, row, "%-7s", Display_scale_of(Mt_Scale_of(obj)));
pn1(77, row, "%-3s", TransExchangeName(obj));
if (Mt_ObjType_of(obj) == BOND_TYPE)
{
if ((Mt_HeFlags_of(obj) & ALIAS_MSK) != 0)
pn1(76, row, "%c", 'A');
}
break;

Sep 14 '07 #6

P: n/a

Adrian <nn**@bluedreamer.comwrote in message...
>
I am trying to clean up and rewrite some old code that is creating
rows for screen display that uses cursor position and printf type
args.

Thing is I can never tell exactly how long the row could be. And the
version of snprintf on this platform returns -1 if printed string is
longer then buffer rather then what should be then length.
size_t rows(25);
size_t cols(80);
std::vector<std::stringvScrn( rows, std::string( cols, ' ' ) );

So, now you have an 25x80 "screen". But, now you can change it's size at
will.

// add a row
vScrn.push_back( std::string( cols, ' ' ) );

// make all cols 90
for( size_t i(0); i < vScrn.size(); ++i ){
vScrn.at(i).append( 10, ' ' ); // add 10 spaces
} // for(i)

// make it 20x50
vScrn.resize( 20 );
for( size_t i(0); i < vScrn.size(); ++i ){
vScrn.at(i).resize( 50 );
} // for(i)

// Change the char at row 3, col 22, to "A":
vScrn.at(2).at( 21 ) = 'A';

// send the whole thing to cout:
std::copy( vScrn.begin(), vScrn.end(),
std::ostream_iterator<std::string>( std::cout, "\n" ) );

Etc..

You could put it all in one std::string, but then you'd need to keep track
of the new-line chars ('\n').
std::string( " line one.\n line two.\n line three.\n ....." );

I much prefer the vector of strings. Use the power of the standard C++
library.
>
I was hoping with seeking in a stringstream I could keep almost the
same arguments
For a learning excersize, go ahead. Otherwise, re-design it from the ground
up. I'm still fighting an C_to_C++ project I started years ago, a real mess.
(if only I knew then what I know now! <G>).
>
Example of old stuff below:
pn1(0, row, "%-10s", HemName_of(obj));
Without knowing what declaration of 'pn1' is, it's hard to give you an
example.

Think it over, and come back here if/when you need help.

--
Bob R
POVrookie
Sep 14 '07 #7

P: n/a
Adrian wrote:
On Sep 14, 3:34 am, James Kanze <james.ka...@gmail.comwrote:
I'm not too sure what you're doing, but it sounds like what you
want is something like std::string or std::vector<char>, using
resize( ' ' ) as needed.
I am trying to clean up and rewrite some old code that is creating
rows for screen display that uses cursor position and printf type
args.
But that doesn't really tell me much. The obvious way to
represent rows in a screen display would be something like:
typedef std::vector< char Row ;
std::vector< Row display ;
Thing is I can never tell exactly how long the row could be. And the
version of snprintf on this platform returns -1 if printed string is
longer then buffer rather then what should be then length.
What I'd probably do is use something like the above. Then,
given a request to insert an int 'value' at position i, j, I'd
write something like:

std::ostringstream tmp ;
tmp << value ;
if ( display.size() <= i ) {
display.resize( i + 1 ) ;
}
Row& r = display[ i ] ;
std::string s( tmp.str() ) ;
size_t lastCol = j + s.size() ;
if ( r.size() <= lastCol ) {
r.resize( lastCol + 1, ' ' ) ;
}
std::copy( s.begin(), s.end(), r.begin() + j ) ;
I was hoping with seeking in a stringstream I could keep almost the
same arguments
Example of old stuff below:
pn1(0, row, "%-10s", HemName_of(obj));
pn1(11, row, "%-2s", Area_sh_nms[Mt_AreaFromCnum(Mt_Cnum_of(obj))]);
pn1(14, row, "%-8d", Mt_Cnum_of(obj));
pn1(23, row, "%-6s", Mt_ObjTypeName_of(obj));
pn1(30, row, "%-7s", Mt_CmdtyName_of(obj));
The only real problem will be handling the formatting strings.
And it shouldn't be too difficult to parse them, mapping them to
fmtflags, width and precision arguments for the ostringstream.
Or check out boost::format, which I think can handle about 95%
of the formatting flags---only a few of the more exotic cases
aren't handled. (The syntax of boost::format is rather wierd,
since it uses %, rather than <<, as the inserter, which rapidly
leads to fairly unreadable code. But if you're only inserting
one value at a time, and that value is always a parameter to the
function, it shouldn't be too bad. I used to have a Format
class myself; as a result of a challenge, I'd actually
implemented 100% of the printf formatting, plus the X/Open
extensions, along with all sorts of hooks to make it easy for
user defined types to do as well, if they had semantics more or
less like those of a floating point or integral number. I
stopped maintaining it sometime back, however, because I never
used it; the ostream formatting is so much more readable.)

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Sep 15 '07 #8

This discussion thread is closed

Replies have been disabled for this discussion.