Re: c++ begginer program help
On Apr 6, 12:00 pm, "Jim Langston" <tazmas...@rocketmail.com> wrote:
<sren...@yahoo.com> wrote in message
news:1175710245.893820.280900@w1g2000hsg.googlegroups.com...
On the whole, your comments are on target, and correspond to
generally accepted good programming, but in thie particular
case...
[...]
forget about char* and use std::string, then you can use find, will make
your life a LOT easier.
Whatever you do, don't use char*, that's for sure. But in this
case, I don't think that std::string is really the answer
either.
[...]
How about:
while ( std::getline( line ) )
Generally (say about 99 times out of 100), I'd recommend the
same thing. If the grammar is line oriented, it makes
resynchronizing after an error child's play, and even if the
grammar isn't line oriented, it provides as good a "chunk" as
anything else, and makes it easy to indicate line numbers in the
error messages.
In his case, however, he isn't doing any real parsing, and
there's no error handling, so these considerations don't come
into play. And one of his constructs (a block comment) can
extend across line boundaries---I think you'll find handling it
correctly no easy job if you insist on reading line by line. In
this one particular case (again: it's an exception---your
suggestions are better 99% of the time), I'd use a sliding
window in the file, implemented using std::deque<char>. It took
me less than 5 minutes to come up the following general sketch:
class Window
{
public:
explicit Window( size_t size = 2 ) ;
size_t fill( std::istream& source ) ;
void pop( size_t n = 1 ) ;
char top() const ;
size_t size() const ;
bool matchPrefix( std::string const& target )
const ;
private:
size_t myMaxSize ;
std::deque< char > myWindow ;
} ;
Window::Window(
size_t size )
: myMaxSize( size )
{
}
size_t
Window::fill(
std::istream& source )
{
while ( source && myWindow.size() != myMaxSize ) {
char ch ;
if ( source.get( ch ) ) {
myWindow.push_back( ch ) ;
}
}
return myWindow.size() ;
}
void
Window::pop(
size_t n )
{
myWindow.erase(
myWindow.begin(),
myWindow.begin() + std::min( myWindow.size(), n ) ) ;
}
char
Window::top() const
{
assert( ! myWindow.empty() ) ;
return myWindow.front() ;
}
size_t
Window::size() const
{
return myWindow.size() ;
}
bool
Window::matchPrefix(
std::string const& target ) const
{
return myWindow.size() >= target.size()
&& std::equal( target.begin(), target.end(),
myWindow.begin() ) ;
}
int
main()
{
enum State
{
start,
inBlockComment,
inLineComment
} state = start ;
Window w ;
while ( w.fill( std::cin ) != 0 ) {
switch ( state ) {
case start :
if ( w.matchPrefix( "//" ) ) {
state = inLineComment ;
w.pop( 2 ) ;
} else if ( w.matchPrefix( "/*" ) ) {
state = inBlockComment ;
w.pop( 2 ) ;
} else {
std::cout << w.top() ;
w.pop( 1 ) ;
}
break ;
case inBlockComment :
if ( w.matchPrefix( "*/" ) ) {
state = start ;
w.pop( 2 ) ;
} else {
w.pop( 1 ) ;
}
break ;
case inLineComment :
if ( w.matchPrefix( "\n" ) ) {
state = start ;
} else {
w.pop( 1 ) ;
}
break ;
}
}
return 0 ;
}
Hmm.. I dont' see where you checked for ending a block comment, or where =
you
are not writing anything if you started a block comment.
Which will be non-trivial problems if he reads line by line.
--
James Kanze (Gabi Software) email: james.kanze@gmail.com
Conseils en informatique orient=E9e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S=E9mard, 78210 St.-Cyr-l'=C9cole, France, +33 (0)1 30 23 00 34