example4-25 of c++cookbook

E

eric

Dear advanced programers:

In that book's chapter 4 Section 16: Wrapping Lines in a Text File
author desribe:
Problem
You want to "wrap" text at a spicific number of characters in a file.
For example, if
you want to wrap text at 72 characters, you would insert a new-line
character after
every 72 characters in the file. If the file contains human-readable
text, you probably
want to avoid splitting words.
Solution
Write a function that uses input and output streams to read in
characters with
istream::get(char), do some bookkeeping, and wirte our characters with
ostream::
put(char). Example 4-25 shows how to do this for text files that
contain human-
readable text without splitting words.
c++ cookbook 's example source code is here
http://examples.oreilly.com/9780596007614/

------------------------------------------------------
eric@eric-laptop:~/cppcookbook/download$ g++ 4-25.cpp
4-25.cpp: In function ‘void textWrap(std::istream&, std::eek:stream&,
size_t)’:
4-25.cpp:19:21: error: ‘ltrimws’ was not declared in this scope
eric@eric-laptop:~/cppcookbook/download$ cat 4-25.cpp
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <string>
#include <cctype>
#include <functional>

using namespace std;

void textWrap(istream& in, ostream& out, size_t width) {

string tmp;
char cur = '\0';
char last = '\0';
size_t i = 0;

while (in.get(cur)) {
if (++i == width) {
ltrimws(tmp); // ltrim as in Recipe
out << '\n' << tmp; // 4.1
i = tmp.length( );
tmp.clear( );
} else if (isspace(cur) && // This is the end of
!isspace(last)) { // a word
out << tmp;
tmp.clear( );
}
tmp += cur;
last = cur;
}
}

int main(int argc, char** argv) {
if (argc < 3)
return(EXIT_FAILURE);

int w = 72;
ifstream in(argv[1]);
ofstream out(argv[2]);

if (!in || !out)
return(EXIT_FAILURE);

if (argc == 4)
w = atoi(argv[3]);

textWrap(in, out, w);

out.close( );

if (out)
return(EXIT_SUCCESS);
else
return(EXIT_FAILURE);
}
eric@eric-laptop:~/cppcookbook/download$
---------------------------------------------------------------------------------------
as you can see, it can not compile
so I put the definition of ltrimws
similar as rtrimws in Example4-4 in it
Here is my modified version
-------------------------------------
// Exmaple 4-25 Wrapping text
#include <iostream>
#include <cstdlib>
#include <fstream>
#include <string>
#include <cctype>
#include <cwctype>
#include <functional>

using namespace std;
/
**********************************************************************/

template<typename T, typename F>
void ltrimws(basic_string<T>& s, F f) {

if (s.empty())
return;

typename basic_string<T>::iterator p;
for (p = s.end(); p != s.begin() && f(*--p););

if (!f(*p))
p++;

s.erase(p, s.end());
}

// Overloads to make cleaner calling for client code
void ltrimws(string& s) {
// rtrimws(s, isspace);
ltrimws(s, static_cast<int(&)(int)> (isspace));
}

void ltrimws(wstring& ws) {
ltrimws(ws, iswspace);
}




/
**********************************************************************/
void textWrap(istream& in, ostream& out, size_t width) {
string tmp;
char cur='\0';
char last= '\0';
size_t i= 0;

while (in.get(cur)) {
if (++i == width) {
ltrimws(tmp); // ltrim as in Recipe
//ltrim(tmp);
// trim(tmp);
out << '\n' << tmp; // 4.1
i= tmp.length();
tmp.clear();
} else if (isspace(cur) && // This is the end of
!isspace(last)) { // a word
out << tmp;
tmp.clear();
}
tmp += cur;
last= cur;
}
}

int main(int argc, char** argv) {
if (argc < 3)
return(EXIT_FAILURE);

int w= 72;
ifstream in(argv[1]);
ofstream out(argv[2]);

if (!in || !out)
return(EXIT_FAILURE);

if (argc == 4)
w= atoi(argv[3]);

textWrap(in, out, w);

out.close();

if (out)
return(EXIT_SUCCESS);
else
return(EXIT_FAILURE);
}
-----------------------------------------------------------------------------------------------------------------------------
It certainly didn't work good
This is my test text and run result
---------------------------------------------
The fucntion template in Example 4-4, rtrimws, is a generic
function
washington template, similar to the previous example, that accepts
a
basic-microsoftWord_string and trims whitespace from the end of it.

----------------------------------------------
../a.out testin7 resultout7
eric@eric-laptop:~/cppcookbook/ch4$ cat resultout7
The fucntion template in Example 4-4, rtrimws, is a generic function

washington template, similar to the previous example, that accepts
a
basic-microsoftWord_string and trims whitespace from the end of
it.eric@eric-laptop:~/cppcookbook/ch4$
 
K

Kleuskes & Moos

<snip>

What relation (if any) does this have to the stated subject of this
newsgroup?
 
J

James Kuyper

<snip>

What relation (if any) does this have to the stated subject of this
newsgroup?

Which newsgroup? It's cross-posted to 4.

I didn't see the message you're responding to, but neither relevance nor
coherence are priorities for io_x, so there's not much point in
chastising him about them.
 
M

Miss Hadiya Abdul Hafiz

Here is my idea:
Parse the input line by line till end of file, at the same time count
characters up to 72 chars.
std::copy() from the 73rd char till end of line, to another string.
Use std::front_inserter() to append another string to the beginning of the next
line.
Repeat until std::copy() of another string is empty() returns true, then break.

// Comments: urm... i might be breaking out too early here, then the last sentence is truncated :(

What do you think? Does this algorithm work or there is a better way to go about it?
 

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

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,056
Latest member
GlycogenSupporthealth

Latest Threads

Top