any improvements for this programme

A

arnuld

/* C++ Primer 4/e
* section 3.2 - String Standard Library

* exercise 3.8
* STATEMENT
* write a programme to read strings from standard input, concatenate
all of them * in one string where each input string is seperated by
whitespace and then print it. */

#include <iostream>
#include <string>

int main()
{
std::string input_string, final_string;

while(std::cin >> input_string)
if(final_string.empty()) // without "if" we will get a
whitespace
final_string += input_string; // at the beginning of final_string.
else
final_string = final_string + " " + input_string;

std::cout << final_string << std::endl;

return 0;
}


it works fine


-- http://arnuld.blogspot.com
 
I

Ian Collins

arnuld said:
/* C++ Primer 4/e
* section 3.2 - String Standard Library

* exercise 3.8
* STATEMENT
* write a programme to read strings from standard input, concatenate
all of them * in one string where each input string is seperated by
whitespace and then print it. */

#include <iostream>
#include <string>

int main()
{
std::string input_string, final_string;

while(std::cin >> input_string)
if(final_string.empty()) // without "if" we will get a
whitespace
final_string += input_string; // at the beginning of final_string.
else
final_string = final_string + " " + input_string;

std::cout << final_string << std::endl;

return 0;
}
Put your expressions in braces, it makes the code clearer and easier to
maintain.

Try and avoid posting code with end of line comments that wrap, C style
comments are safer for Usenet.
 
A

arnuld

Put your expressions in braces, it makes the code clearer and easier to
maintain.

ok.. done
Try and avoid posting code with end of line comments that wrap,

i donot get it. what are "end of line comments that wrap" ?
C style comments are safer for Usenet.

ok you said /* */ are safer for USENET but not for C++ programmer ??
 
I

Ian Collins

arnuld said:
ok.. done


i donot get it. what are "end of line comments that wrap" ?
Look at how your code appeared after you posted it, your comment after
the if wrapped to the next line, so if anyone tried to copy and past the
code to compile it, they would have to fix up the code first.
ok you said /* */ are safer for USENET but not for C++ programmer ??

if(final_string.empty()) // without "if" we will get a
whitespace

won't compile

if(final_string.empty()) /* without "if" we will get a
whitespace */

will.
 
J

Jim Langston

arnuld said:
/* C++ Primer 4/e
* section 3.2 - String Standard Library

* exercise 3.8
* STATEMENT
* write a programme to read strings from standard input, concatenate
all of them * in one string where each input string is seperated by
whitespace and then print it. */

#include <iostream>
#include <string>

int main()
{
std::string input_string, final_string;

while(std::cin >> input_string)
if(final_string.empty()) // without "if" we will get a
whitespace
final_string += input_string; // at the beginning of final_string.

At this point final_string is empty. += is rather unneeded, although it
would work. I would rather change this line to:
final_string = input_string;

Does the exact same thing in the end, but makes it clearer what is going on.
 
G

Guest

/* C++ Primer 4/e
* section 3.2 - String Standard Library

* exercise 3.8
* STATEMENT
* write a programme to read strings from standard input, concatenate
all of them * in one string where each input string is seperated by
whitespace and then print it. */

#include <iostream>
#include <string>

int main()
{
std::string input_string, final_string;

while(std::cin >> input_string)

To me a string can contain white-spaces, this code reads words and
concatenates them. The question is a bit vague on this issue but I'd use
getline() and use the definition string == line. Just a thought.
 
M

Markus Schoder

Put your expressions in braces, it makes the code clearer and easier to
maintain.

That is in no way a generally accepted opinion. I find the code more
readable without the braces.
 
J

Jerry Coffin

/* C++ Primer 4/e
* section 3.2 - String Standard Library

* exercise 3.8
* STATEMENT
* write a programme to read strings from standard input, concatenate
all of them * in one string where each input string is seperated by
whitespace and then print it. */

#include <iostream>
#include <string>

int main()
{
std::string input_string, final_string;

while(std::cin >> input_string)
if(final_string.empty()) // without "if" we will get a
whitespace
final_string += input_string; // at the beginning of final_string.
else
final_string = final_string + " " + input_string;

std::cout << final_string << std::endl;

return 0;
}

I'd generally do things a bit differently. Right now, you have a (mildly
messy) if statement in the inner loop. Unless it's crucial that there
NOT be an extra space after the final string, I'd just add a space after
the end of each string, which would simplify the code considerably.

Unless you're going to do something else with the data while it's stored
as a big string, I'd avoid using up the storage, and just copy data from
input to output, with padding added as necessary.

I'd consider using a standard algorithm instead of an explicit loop. The
first simplification (often) makes this step easier since it allows all
input to be treated uniformly.

Putting all those together gives a program that's quite a bit simpler,
but gives similar results:

#include <iostream>
#include <iterator>
#include <algorithm>

int main() {
std::copy(std::istream_iterator<std::string>(std::cin),
std::istream_iterator<std::string>(),
std::eek:stream_iterator<std::string>(std::cout, " "));
return 0;
}

To meet the original specification, we can use a stringstream instead of
copying directly to cout, and remove the extra space from the
intermediate string:

int main() {
std::eek:stringstream temp;

std::copy(std::istream_iterator<std::string>(std::cin),
std::istream_iterator<std::string>(),
std::eek:stream_iterator<std::string>(temp, " "));

std::string data = std::string(temp.str(),
0,
temp.str().length()-1);

std::cout << data;

return 0;
}
 
A

arnuld

I'd generally do things a bit differently. Right now, you have a (mildly
messy) if statement in the inner loop. Unless it's crucial that there
NOT be an extra space after the final string, I'd just add a space after
the end of each string, which would simplify the code considerably.

yes, you are right but someone mentioned it on the newsgroup, IIRC.
#include <iostream>
#include <iterator>
#include <algorithm>

int main() {
std::copy(std::istream_iterator<std::string>(std::cin),
std::istream_iterator<std::string>(),
std::eek:stream_iterator<std::string>(std::cout, " "));
return 0;
}

this code runs but it prints everything as sson as i press "Enter". i
think the problem wants us to print the input only when EOF is
encountered.
int main() {
std::eek:stringstream temp;

std::copy(std::istream_iterator<std::string>(std::cin),
std::istream_iterator<std::string>(),
std::eek:stream_iterator<std::string>(temp, " "));

std::string data = std::string(temp.str(),
0,
temp.str().length()-1);

std::cout << data;

return 0;
}

this gives error at line: "std::eek:stringstream temp;"

{arnuld@arch cpp }% g++ -ansi -pedantic -Wall -Wextra RL_3.8.cpp
RL_3.8.cpp: In function ‘int main()’:
RL_3.8.cpp:26: error: aggregate ‘std::eek:stringstream temp’ has incomplete type and cannot be defined
RL_3.8.cpp:32: error: ‘length’ was not declared in this scope
RL_3.8.cpp:32: error: expected primary-expression before ‘(’ token
RL_3.8.cpp:32: error: expected unqualified-id before ‘(’ token
{arnuld@arch cpp }%


-- http://arnuld.blogspot.com
 
J

James Kanze

i donot get it. what are "end of line comments that wrap" ?

Some newreaders wrap lines that are too long, which results in
the end of the comment showing up on a new line (without a
leading //).

The easiest way to avoid this is to limit your line length; I
think 64 characters is generally safe.

An even easier way is to suppose that people are intelligent
enough to recognize the problem, and fix it. Whether this is an
appropriate solution depends on the purpose of your posting is:
if it is sample code that we should copy/paste into an editor,
then compile, then it's not a good idea; if the goal is just to
illustrate a point, so that something can be better understood,
it's usually OK.
ok you said /* */ are safer for USENET but not for C++ programmer ??

There's nothing "unsafe" about C style comments. They're just a
pain to maintain in project code.
 
J

James Kanze

I'd generally do things a bit differently. Right now, you have a (mildly
messy) if statement in the inner loop. Unless it's crucial that there
NOT be an extra space after the final string, I'd just add a space after
the end of each string, which would simplify the code considerably.

In this case, you're probably right. For this specific case, I
would also consider:

while ( std::cin >> input_string ) {
final_string += ' ' ;
final_string += input_string ;
}
std::cout << final_string.substr( 1 ) << std::endl ;

or:

while ( std::cin >> input_string ) {
if ( ! final_string.empty() ) {
final_string += ' ' ;
}
final_string += input_string ;
}

More generally, however, I use something like:

int inLineCount = 0 ;
while ( whatever ) {
if ( inLineCount == 0 ) {
output line header...
} else {
output separator...
}
output value
++ inLineCount ;
if ( inLineCount >= maxInLine ) {
output end of line...
inLineCount = 0 ;
}
}

It's a standard pattern, which covers a lot of cases. In
practice, I find it more effort to eliminate the if's in the
special cases than to just use a standard pattern everywhere.
 
J

Jerry Coffin

yes, you are right but someone mentioned it on the newsgroup, IIRC.

I didn't see it, but I may (easily) have missed a post...
this code runs but it prints everything as sson as i press "Enter". i
think the problem wants us to print the input only when EOF is
encountered.

Yes -- rather than storing the data, it simply processes data and
produces output immediately.
this gives error at line: "std::eek:stringstream temp;"

Try adding:

#include <sstream>

up toward the beginning of the file and see if it doesn't help.
 
A

arnuld

I didn't see it, but I may (easily) have missed a post...

yes, it is not there and nobosy mentioned it. i think that may be a
thought that came to mind while writing the programme 1st time :)
...[SNIPPED]........
std::copy(std::istream_iterator<std::string>(std::cin),
std::istream_iterator<std::string>(),
std::eek:stream_iterator<std::string>(temp, " "));

std::string data = std::string(temp.str(),
0,
temp.str().length()-1);

std::cout << data;

return 0;
}
}
this gives error at line: "std::eek:stringstream temp;"
Try adding: #include <sstream>
up toward the beginning of the file and see if it doesn't help.

yes it works. dinot know that "ostream_iterator" is defined in "<sstream>"
header. BTW, it eats all newlines in the end of input, so i added a
"std::cout << std::endl" just before "return 0", so that the output
doesnot came on the same line as my hostnam eon terminal :)



-- http://arnuld.blogspot.com
 
J

James Kanze

(e-mail address removed) says...
...[SNIPPED]........
std::copy(std::istream_iterator<std::string>(std::cin),
std::istream_iterator<std::string>(),
std::eek:stream_iterator<std::string>(temp, " "));
std::string data = std::string(temp.str(),
0,
temp.str().length()-1);
std::cout << data;
return 0;
}
}
this gives error at line: "std::eek:stringstream temp;"
Try adding: #include <sstream>
up toward the beginning of the file and see if it doesn't help.
yes it works. dinot know that "ostream_iterator" is defined in
"<sstream>" header.

The <sstream> header is for the ostringstream. ostream_iterator
is defined in <iterator>. (But any standard header is allowed
BTW, it eats all newlines in the end of input, so i added a
"std::cout << std::endl" just before "return 0", so that the output
doesnot came on the same line as my hostnam eon terminal :)

You mean that it doesn't generate a final newline on output.
Jerry just forgot that, I suppose. (I've seen shells which
always output an extra newline before the prompt, just to avoid
this problem. The problem then is that you have an extra emptly
line everytime you run a program which works correctly.)
 
J

Jerry Coffin

[ ... ]
yes it works. dinot know that "ostream_iterator" is defined in "<sstream>"
header.

It's not -- the iterator types are declared in said:
BTW, it eats all newlines in the end of input, so i added a
"std::cout << std::endl" just before "return 0", so that the output
doesnot came on the same line as my hostnam eon terminal :)

Yup -- I left out that detail. As an aside, I'd note that std::newline
flushes the output stream along with adding a newline character. Unless
you really need this behavior, simply writing out a "\n" accomplishes
the same thing, generally more efficiently. In this case, you're doing
it immediately before the stream is destroyed, which flushes the stream
in any case, so you're flushing the stream twice for no particularly
good reason. One extra flush rarely means much, but it's something to
keep in mind if (for example) you're writing out a large amount of data
in a loop -- in such a situation, flushing after every line can make the
program considerably slower.
 
J

James Kanze

[ ... ]
Yup -- I left out that detail. As an aside, I'd note that std::newline
flushes the output stream along with adding a newline character. Unless
you really need this behavior, simply writing out a "\n" accomplishes
the same thing, generally more efficiently.

You're an experienced programmer. You automatically know when
you need to flush, without thinking about it, and your programs
probably don't core dump zillions of times before you finally
get them running. The default is (or should be) std::endl, so
that you get the flush. So that in case of a core dump, your
output reflects (sort of) how far you've gotten.
In this case, you're doing
it immediately before the stream is destroyed, which flushes the stream
in any case, so you're flushing the stream twice for no particularly
good reason. One extra flush rarely means much, but it's something to
keep in mind if (for example) you're writing out a large amount of data
in a loop -- in such a situation, flushing after every line can make the
program considerably slower.

If the data set is large enough, yes, you may have to think
about it. I wouldn't put the use of '\n' up there with
premature optimizations. But for beginners, I still think that
std::endl is the better default. (In my professional code, it's
always std::endl. But that's because the only streaming output
is to a log file, where you definitely do want the flush.)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,767
Messages
2,569,572
Members
45,045
Latest member
DRCM

Latest Threads

Top