- Comparing strings with if else - 7 Updates
- Structure clash - problem statement & supporting code - 2 Updates
- Structure clash - problem statement & supporting code - 1 Update
- structure clash - output driven solution - 2 Updates
- structure clash - flow based solution - 1 Update
- Structure clash - input driven solution - 1 Update
- Stackoverflow - a fascist web-site. - 2 Updates
Juha Nieminen <nospam@thanks.invalid>: Nov 09 09:38AM > ( char const * const s, > char const * const s1 ) Is that deliberate obfuscation? (Hint: Is there any rational reason to not to use 's1' and 's2'? Or even better, something even clearer, like 'str1' and 'str2'.) --- news://freenews.netfront.net/ - complaints: news@netfront.net --- |
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Nov 09 12:08PM +0100 On 11/9/2015 10:38 AM, Juha Nieminen wrote: >> ( char const * const s, >> char const * const s1 ) > Is that deliberate obfuscation? I prefer "a" and "b" for such naming. But I can understand "sI" and "sII". And in the case of a source and a destination, the old 1970's C convention is "s" and "d". Cheers, - Alf |
Juha Nieminen <nospam@thanks.invalid>: Nov 09 12:11PM > But I can understand "sI" and "sII". > And in the case of a source and a destination, the old 1970's C > convention is "s" and "d". Why the love for brevity? Why must everything use as few characters as possible? But as said, even if you must use short names, I think 'str1' and 'str2' ought to do. Although if we are talking about comparing two things, a common naming convention is 'lhs' and 'rhs' (especially for very short comparison functions). --- news://freenews.netfront.net/ - complaints: news@netfront.net --- |
Gareth Owen <gwowen@gmail.com>: Nov 09 04:06PM >> convention is "s" and "d". > Why the love for brevity? Why must everything use as few characters as > possible? Never understood it drives me mad. I am currently working on a departed co-worker's code which is full of obfuscated snippets like const uint8_t *b_r = src; ... const uint8_t *t_b_r = b_r; uint8_t *t_s_b_r = s_b_r; for(int k=0;k<k_end;++k, br += stride) { *(s_b_r++) = *(b_r); } and when you refactor it it turns into something insanely clear: const uint8_t *src_row = src + row*width; uint8_t *dst_row = dst + row*dst_width; for(int col=0;k<ncols;++col) { dst_row[col] = src_row[col*stride]; } He's also a big fan of iterating over arrays with int l = len; for(;l--;) { arr[l] = whatever(); } seemingly *just* to avoid the wearisome job of typing an idiomatic for-loop. |
Paavo Helde <myfirstname@osa.pri.ee>: Nov 09 11:33AM -0600 >> Why the love for brevity? Why must everything use as few characters as >> possible? > Never understood it drives me mad. I am currently working on a departed > { > *(s_b_r++) = *(b_r); > } You are lucky if this is the most obfuscated code that you see :-) > { > dst_row[col] = src_row[col*stride]; > } This code contains a multiplication in inner loop, so the original code might have had better performance with old hardware and compilers. Nowadays this probably does not matter any more. Cheers Paavo |
Jorgen Grahn <grahn+nntp@snipabacken.se>: Nov 09 06:50PM On Mon, 2015-11-09, Gareth Owen wrote: >>> convention is "s" and "d". >> Why the love for brevity? Why must everything use as few characters as >> possible? Sometimes there's just not anything more to say. > Never understood it drives me mad. I am currently working on a > departed co-worker's For some reason, at first I read "deceased". > { > *(s_b_r++) = *(b_r); > } To me, that's fairly long /and/ content-less names. The way he uses underscores to separate words and ease readability is almost sadistic. But I suspect it made perfect sense to him, and was written in good faith. /Jorgen -- // Jorgen Grahn <grahn@ Oo o. . . \X/ snipabacken.se> O o . |
legalize+jeeves@mail.xmission.com (Richard): Nov 09 09:12PM [Please do not mail me a copy of your followup] Jorgen Grahn <grahn+nntp@snipabacken.se> spake the secret code >>> Why the love for brevity? Why must everything use as few characters as >>> possible? >Sometimes there's just not anything more to say. In 1978, my team went insane with "coding style" guidelines. One programmer started writing (in C++ identifier form) the_loop_variable instead of i to get code like: for (int the_loop_variable = 0; the_loop_variable < 10; ++the_loop_variable) { cout << the_loop_variable << '\n'; } It uniformly made his code harder to read. This is the difference between guidelines and rules. When there is a rule that says "single letter variable names aren't allowed", then you get the above nonsense. When there is a guideline that says "avoid unnecessarily abbreviated variable names" or "use variable names to reveal your intent", then loop variables like i or source/destination variables for copying like s and d are just fine. They are idiomatic and common enough that people aren't confused in reading the code. Of course, idiomatic programming is something that you pick up from reading other people's code and having a discussion about it. Anyone can learn the syntax from a book describing the grammar, but they are unlikely to pick up the idioms without reading realistic code. K&R did a good job of explaining both syntax and idioms in "The C Programming Language". Bjarne Stroustrup does a similarly good job in "The C++ Programming Language". What a pity it is that so many people refuse to listen to the creators of either language. -- "The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline> The Computer Graphics Museum <http://computergraphicsmuseum.org> The Terminals Wiki <http://terminals.classiccmp.org> Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com> |
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Nov 09 03:57PM +0100 From somewhere on the net: ------------------------------------------------------------------------- Peter Naur's "Telegram Problem" 1 "Write a program that takes a number w, then accepts lines of text and outputs lines of text, where the output lines have as many words as possible but are never longer than w characters. Words may not be split, but you may assume that no single word is too long for a line." 2 Originally described in 197x by Peter Naur, 2005 Turing Award Winner. 3 This is essentially word-wrapping within a paragraph of a text editor. "As such, it is a classic ObjectOriented problem, used as an example in the Design Patterns Book." 4 It is surprisingly difficult to specify correctly, and to design a correct program in Java or C++. 5 Do a requirement analysis. E.g.: What assumptions must we make so that this problem is doable? ------------------------------------------------------------------------- I haven't the foggiest idea about 5, and I don't see why 4, and 3 is pretty baffling to me, and regarding 2 I think I first saw this problem in a COBOL course where it was used to illustrate Jackson Structured Programming, but, I've coded up three C++ solutions which I'll post, I think in separate threads, so that you sharks can rip them to pieces. :) All three solutions use the following support code, coded up for the exercise, which I KNOW has its problems, and may not even be correct. So ;-) <file "cppx.hpp"> #pragma once #include <assert.h> // assert #include <condition_variable> // std::condition_variable #include <deque> // std::deque #include <iostream> #include <mutex> // std::mutex, std::unique_lock #include <stddef.h> // ptrdiff_t #include <stdexcept> // std::runtime_error #include <string> // std::string, std::wstring, std::getline #include <utility> // std::move #include <vector> // std::vector namespace cppx { using std::condition_variable; using std::deque; using std::move; using std::mutex; using std::runtime_error; using std::string; using std::unique_lock; using std::vector; using std::wcin; using std::wistream; using std::wstring; using Byte_string = string; using Size = ptrdiff_t; using String = wstring; auto hopefully( bool const condition ) -> bool { return condition; } auto fail( Byte_string const& s ) -> bool { throw runtime_error( s ); } template< class C > auto n_items( C const& c ) -> Size { return c.size(); } template< class Item > class Boxed { private: vector<Item> vec_; public: auto is_empty() const -> bool { return n_items( vec_ ) == 0; } explicit operator bool() const { return !is_empty(); } auto item() -> Item& { return vec_.at( 0 ); } auto item() const -> Item const& { return vec_.at( 0 ); } auto operator=( Boxed&& other ) -> Boxed& { vec_ = move( other.vec_ ); return *this; } static // Named creation for readability. auto empty() -> Boxed { return {}; } Boxed(){} explicit Boxed( Item o ) { vec_.push_back( move( o ) ); } Boxed( Boxed&& other ) : vec_( move( other.vec_ ) ) {} }; auto input_line( wistream& stream = wcin ) -> Boxed<String> { String line; if( getline( stream, line ) ) { return Boxed<String>( move( line ) ); } return Boxed<String>::empty(); } class Non_copyable { private: Non_copyable( Non_copyable const& ) = delete; auto operator=( Non_copyable const& ) -> Non_copyable& = delete; public: auto operator=( Non_copyable&& ) -> Non_copyable& = default; Non_copyable() = default; Non_copyable( Non_copyable&& ) = default; }; class Non_movable { private: Non_movable( Non_movable&& ) = delete; auto operator=( Non_movable&& ) -> Non_movable = delete; public: auto operator=( Non_movable const& ) -> Non_movable& = default; Non_movable() = default; Non_movable( Non_movable const& ) = default; }; struct ConditionVariable : public Non_copyable , public Non_movable { private: mutex mx_; condition_variable cv_; int n_signals_; int n_waits_; public: void signal() { unique_lock<mutex> lock( mx_ ); ++n_signals_; if( n_waits_ > 0 ) { cv_.notify_one(); } } void wait() { unique_lock<mutex> lock( mx_ ); if( n_signals_ == 0 ) { ++n_waits_; cv_.wait( lock, [&]() -> bool { return n_signals_ > 0; } ); --n_waits_; } --n_signals_; } ConditionVariable( int const initial_signals_count = 0 ) : n_signals_( initial_signals_count ) , n_waits_( 0 ) {} }; // Move-construction of Item must be non-throwing. template< class Item, Size capacity = 1 > class Pipe { private: deque<Item> q_; mutex q_mx_; ConditionVariable q_room_; ConditionVariable q_items_; public: void put( Item item ) { q_room_.wait(); { unique_lock<mutex> lock( q_mx_ ); q_.push_back( move( item ) ); assert( n_items( q_ ) <= capacity ); } q_items_.signal(); } auto get() -> Item { q_items_.wait(); { unique_lock<mutex> lock( q_mx_ ); assert( n_items( q_ ) > 0 ); Item result( move( q_.front() ) ); q_.pop_front(); lock.unlock(); // Unclean. q_room_.signal(); return result; } } Pipe() : q_room_( capacity ) , q_items_() { // q_.reserve( capacity ); // There is no such operation :( } }; } // namespace cppx </file> |
scott@slp53.sl.home (Scott Lurndal): Nov 09 04:12PM >and outputs lines of text, where the output lines have as many words as >possible but are never longer than w characters. Words may not be split, >but you may assume that no single word is too long for a line." #!/bin/ksh cat - | fmt -w ${1} -g 97 |
ram@zedat.fu-berlin.de (Stefan Ram): Nov 09 03:47PM >and outputs lines of text, where the output lines have as many words as >possible but are never longer than w characters. Words may not be split, >but you may assume that no single word is too long for a line." So, the text output does not have to have a relation to the text input? Then, I'd just use the word »I«. That way, I can fit many words on a line: I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I |
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Nov 09 03:58PM +0100 #include "cppx.hpp" //using std::move; using std::wcin; using std::wcout; using cppx::Boxed; using cppx::hopefully; using cppx::fail; using cppx::n_items; using cppx::String; #include <functional> using std::function; #include <sstream> using std::wistringstream; #include <string> using std::stoi; using std::getline; auto std_line_input() -> Boxed<String> { return cppx::input_line(); } class Word_reader { private: function< Boxed<String>() > input_; wistringstream line_stream_; public: auto next_word() -> Boxed<String> { String word; if( line_stream_ >> word ) { return Boxed<String>( move( word ) ); } Boxed<String> new_line; do { new_line = input_(); } while( (not new_line.is_empty()) and n_items( new_line.item() ) == 0 ); if( not new_line.is_empty() ) { line_stream_.clear(); line_stream_.str( new_line.item() ); if( line_stream_ >> word ) { return Boxed<String>( move( word ) ); } } return Boxed<String>::empty(); } Word_reader( function< Boxed<String>() > line_input ) : input_( line_input ) {} }; class Controllable_word_reader { private: Word_reader reader_; String inserted_word_; bool use_inserted_word_; public: auto next_word() -> Boxed<String> { if( use_inserted_word_ ) { use_inserted_word_ = false; return Boxed<String>( move( inserted_word_ ) ); } return reader_.next_word(); } void insert( String word ) { hopefully( not use_inserted_word_ ) || fail( "Controllable_word_reader::insert" ); inserted_word_ = move( word ); use_inserted_word_ = true; } Controllable_word_reader( function< Boxed<String>() > line_input ) : reader_( line_input ) , use_inserted_word_( false ) {} }; enum class Status { all_finished, more_lines_to_do }; auto output_one_line( int const max_line_length, Controllable_word_reader& reader ) -> Status { auto result = Status::more_lines_to_do; String line; for( ;; ) { Boxed<String> word = reader.next_word(); if( word.is_empty() ) { result = Status::all_finished; break; } int const previous_length = n_items( line ); if( previous_length == 0 ) { line = word.item(); } else if( previous_length + 1 + n_items( word.item() ) > max_line_length ) { reader.insert( move( word.item() ) ); break; } else { line += L' '; line += word.item(); } } if( n_items( line ) > 0 ) { wcout << line << "\n"; } return result; } auto main( int, char** args ) -> int { int const w = stoi( args[1] ); Controllable_word_reader reader{ std_line_input }; for( auto status = Status::more_lines_to_do; status != Status::all_finished; ) { status = output_one_line( w, reader ); } } |
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Nov 09 04:14PM +0100 On 11/9/2015 3:58 PM, Alf P. Steinbach wrote: > [snip code] Well just by posting that code I saw that it erroneously will treat a non-empty line of whitespace as end-of-file. But that's easy to fix. Cheers, - Alf |
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Nov 09 03:59PM +0100 #include "cppx.hpp" // using std::move; Found via ADL anyway. using std::wcout; using cppx::Boxed; using cppx::n_items; using cppx::Pipe; using cppx::String; #include <functional> using std::function; #include <sstream> using std::wistringstream; #include <string> using std::stoi; #include <thread> using std::thread; using Input_func = auto() -> Boxed<String>; using Output_func = void( Boxed<String> ); auto boxed_line_input() -> Boxed<String> { return cppx::input_line(); } void boxed_line_output( Boxed<String> const& box ) { if( not box.is_empty() ) { wcout << box.item() << "\n"; } } void lines_to_words( function<Input_func> const& receive_line, function<Output_func> const& send_word ) { for( ;; ) { Boxed<String> const line = receive_line(); if( line.is_empty() ) { send_word( Boxed<String>::empty() ); return; } else { wistringstream stream( line.item() ); String w; while( stream >> w ) { send_word( Boxed<String>( w ) ); } } } } void words_to_lines( int const max_line_length, function<Input_func> const& receive_word, function<Output_func> const& send_line ) { String line; for( ;; ) { Boxed<String> word_box = receive_word(); if( word_box.is_empty() ) { break; } String& word = word_box.item(); int const previous_length = n_items( line ); if( previous_length == 0 ) { line = move( word ); } else if( previous_length + 1 + n_items( word ) > max_line_length ) { send_line( Boxed<String>( move( line ) ) ); line = move( word ); } else { line += L' '; line += word; } } if( n_items( line ) > 0 ) { send_line( Boxed<String>( move( line ) ) ); } send_line( Boxed<String>::empty() ); } auto main( int, char** args ) -> int { int const w = stoi( args[1] ); Pipe<Boxed<String>> pipe; thread t1( lines_to_words, boxed_line_input, [&]( Boxed<String> s )-> void { pipe.put( move( s ) ); } ); thread t2( words_to_lines, w, [&]()->Boxed<String> { return pipe.get(); }, boxed_line_output ); t1.join(); t2.join(); } |
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Nov 09 03:58PM +0100 #include "cppx.hpp" //using std::move; using std::wcout; using cppx::Boxed; using cppx::n_items; using cppx::String; #include <functional> using std::function; #include <sstream> using std::wistringstream; #include <string> using std::stoi; void standard_output( String const& s ) { wcout << s << "\n"; } class Formatter { private: cppx::String line_; int max_length_; function<void(String)> output_; void flush() { output_( line_ ); line_.clear(); } public: void add( String const& s ) { int const previous_length = n_items( line_ ); if( previous_length == 0 ) {} else if( previous_length + 1 + n_items( s ) > max_length_ ) { flush(); } else { line_ += L' '; } line_ += s; } ~Formatter() { if( n_items( line_ ) > 0 ) { flush(); } } explicit Formatter( int const max_length, function<void(String)> output = standard_output ) : max_length_( max_length ) , output_( move( output ) ) {} }; enum class Status { all_finished, more_lines_to_do }; auto input_one_line( Formatter& formatter ) -> Status { Boxed<String> line = cppx::input_line(); if( line.is_empty() ) { return Status::all_finished; } wistringstream stream( line.item() ); String word; while( stream >> word ) { formatter.add( word ); } return Status::more_lines_to_do; } auto main( int, char** args ) -> int { int const w = stoi( args[1] ); Formatter formatter( w ); for( ;; ) { Status const status = input_one_line( formatter ); if( status == Status::all_finished ) { break; } } } |
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Nov 09 01:09AM On 07/11/2015 20:26, Vlad from Moscow wrote: > As I was already said several times at the same Stackoverflow the problem is that I am from Russia and this is clear from my nickname Vlad from Moscow. > I asked a question at Meta that to discuss the situation but again I was ignored and my question was just removed. > So I am again banned after my correct answer was deliberately down-voted and after I asked a question how to behave in such situations.:) This Usenet newsgroup is concerned with C++ not C mate. /Flibble |
Vlad from Moscow <vlad.moscow@mail.ru>: Nov 09 01:41AM -0800 On Monday, November 9, 2015 at 4:09:39 AM UTC+3, Mr Flibble wrote: > > So I am again banned after my correct answer was deliberately down-voted and after I asked a question how to behave in such situations.:) > This Usenet newsgroup is concerned with C++ not C mate. > /Flibble Yes, I know. Your remark would be very useful if it was written in the thyread at stackoverflow that is being discussed.:) The problem is that many C++ programmers think that C is a subset of C++ and as result make wrong conclusion. |
You received this digest because you're subscribed to updates for this group. You can change your settings on the group membership page. To unsubscribe from this group and stop receiving emails from it send an email to comp.lang.c+++unsubscribe@googlegroups.com. |
No comments:
Post a Comment