1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
|
#include <iostream>
#include <cstring>
const char* const tokens[] = { "and", "the", "ing", "ish", "with", /* etc */ } ;
const char* const symbols[] = { "&", "-", "!g", "!h", "w/", /* etc */ } ;
// sanity check
static_assert( sizeof(symbols) == sizeof(tokens), "#tokens-#symbols mismatch" );
constexpr std::size_t NTOKENS = sizeof(tokens) / sizeof( tokens[0] ) ;
// replace old_len characters at position pos in cstr with newstr
// invariant: pointers are not null, pos and old_len are within bounds
// invariant: the underlying sequence of bytes of cstr is large enough
char* replace( char* cstr, std::size_t pos, std::size_t old_len, const char* newstr )
{
// http://en.cppreference.com/w/cpp/string/byte/strlen
const auto cstrlen = std::strlen(cstr) ;
const auto new_len = std::strlen(newstr) ;
// move the tail right or left to adjust the space required for newstr,
// copy characters from newstr into that space
// http://en.cppreference.com/w/cpp/string/byte/memmove
// http://en.cppreference.com/w/cpp/string/byte/memcpy
const auto nchars = cstrlen-pos-old_len+1 ; // +1 to include the terminating null character
if( old_len != new_len ) std::memmove( cstr+pos+new_len, cstr+pos+old_len, nchars ) ;
std::memcpy( cstr+pos, newstr, new_len ) ;
return cstr ;
}
// convert characters in cstr to
// to short hand from long text if to_short == true
// to long text from short hand if to_short == true
// invariant: pointer is not null
// invariant: cstr is large enough to hold the converted string
char* convert( char* cstr, bool to_short )
{
// original == tokens, replacement == symbols if converting
// from long text to short hand; vice versa otherwise
const auto original = to_short ? tokens : symbols ;
const auto replacement = to_short ? symbols : tokens ;
for( std::size_t i = 0 ; i < NTOKENS ; ++i ) // for each original
{
// http://en.cppreference.com/w/cpp/string/byte/strstr
const auto ptr = std::strstr( cstr, original[i] ) ;
if( ptr != nullptr ) // if found
{
// replace with replacement
replace( cstr, ptr-cstr, std::strlen( original[i] ), replacement[i] ) ;
// continue looking for more originals
return convert( cstr, to_short ) ;
}
}
return cstr ; // no more originals were found; we are done
}
// convert long text to short hand
char* to_short_hand( char* cstr ) { return convert( cstr, true ) ; }
// convert short hand to long_text
char* to_long_text( char* cstr ) { return convert( cstr, false ) ; }
int main()
{
char text[] = "with abc and def and the ghijing and with klmish and the nop with qrst and..." ;
std::cout << text << '\n' ;
std::cout << to_short_hand(text) << '\n' ;
std::cout << to_long_text(text) << '\n' ;
}
|