20071127

Newline terminator in Unix/Linux, Windows and Mac (+convertion methods).

Windows Newline: Carriage Return char(13) ή 0Dh + Line Feed char(10) ή 0Ah.
Unix Newline: Line Feed char(10) ή 0Ah.
Mac OS X Newline: Line Feed char(10) ή 0Ah.
Mac OS up to ver9: Carriage Return char(13) ή 0Dh.

Σε unix ή Windows με cygwin με χρήση sed/perl μπορούμε να μετατρέψουμε txt αρχείο:

sed -e 's/$/\r/' inputfile > outputfile # UNIX to DOS (adding CRs)
sed -e 's/\r$//' inputfile > outputfile # DOS to UNIX (removing CRs)
perl -p -e 's/(\r\n|\n|\r)/\r\n/g' inputfile > outputfile # Convert to DOS
perl -p -e 's/(\r\n|\n|\r)/\n/g' inputfile > outputfile # Convert to UNIX
perl -p -e 's/(\r\n|\n|\r)/\r/g' inputfile > outputfile # Convert to old Mac

Link: en.wikipedia article about Newline.

20071126

Convert a tab delimited file to CSV format using Regular Expressions in vi substitution.

Open the tab delimited file with vi.

a) At the end of each line delete all the whitespaces (one or more):

:1,$s/\s\+$//g

b) Substitute all the whitespaces (one or more) with comma ',' :

:1,$s/\s\+/,/g

Remove all "^M" characters from a file using vi.

To remove all "^M" characters from a file, open it in vi and use this command:
:%s/^M//g

The "^M" in the above line has to be typed in by pressing CTRL+v and then CTRL+M.

Also by :%s/\r\(\n\)/\1/g from here.

Convert all new lines to tab delimited using regex in vi.

1,$s/\n/\t/

For example file f.txt:

a1
a2
a3
..

will be converted to:

a1 a2 a3 ..

Post about Regular Expressions.

20071123

Regular expressions links/briefly.

Regular expressions in Perl.

Perl Regular Expression Quick Reference 1.05.

Perl Regular Expression Tutorial.

C++ Boost.Regex library for Perl Regular Expression Syntax.

Perl Regular Expressions briefly:

\ Quote the next metacharacter
^ Match the beginning of the line
. Match any character (except newline)
$ Match the end of the line (or before newline at the end)
| Alternation
() Grouping
[] Character class

* Match 0 or more times
+ Match 1 or more times
? Match 1 or 0 times
{n} Match exactly n times
{n,} Match at least n times
{n,m} Match at least n but not more than m times

* Match 0 or more times
+ Match 1 or more times
? Match 1 or 0 times
{n} Match exactly n times
{n,} Match at least n times
{n,m} Match at least n but not more than m times

*? Match 0 or more times
+? Match 1 or more times
?? Match 0 or 1 time
{n}? Match exactly n times
{n,}? Match at least n times
{n,m}? Match at least n but not more than m times

\t tab (HT, TAB)
\n newline (LF, NL)
\r return (CR)
\f form feed (FF)
\a alarm (bell) (BEL)
\e escape (think troff) (ESC)
\033 octal char (think of a PDP-11)
\x1B hex char
\c[ control char
\l lowercase next char (think vi)
\u uppercase next char (think vi)
\L lowercase till \E (think vi)
\U uppercase till \E (think vi)
\E end case modification (think vi)
\Q quote (disable) pattern metacharacters till \E

\w Match a "word" character (alphanumeric plus "_")
\W Match a non-word character
\s Match a whitespace character
\S Match a non-whitespace character
\d Match a digit character
\D Match a non-digit character

\b Match a word boundary
\B Match a non-(word boundary)
\A Match only at beginning of string
\Z Match only at end of string, or before newline at the end
\z Match only at end of string
\G Match only where previous m//g left off (works only with /g)

Decoding Regular Expressions

SymbolWhat It MeansExampleWhat It Might Find
+find 1 or more of preceding itemta+ta, taa, taaa
*find 0 or more of preceding itemba*b, ba, baa, baaa
?preceding item is optionalab?cabc, ac
.match any character (except return)1.21 2, 122, 1d2, 1$2
[^x]match any character except xus[^a]usb, usc, usd, use
[0-9]match any digit9021[0-9]90210 through 90219
^match start of line^hellomatches hello only at beginning of line
$match end of lineend$matches end only at end of line
( )group items together(ab)+ab, abab, ababab


20071120

Λεξικά για Firefox/Thunderbird, Open Office για Ελληνικά και Αγγλικά μαζί.

http://daremon.gr/tools.php

C++: Defining/initializing static member(s) within a class.

// file: obj.h
class obj {
public:
obj(void) { }; // ctor
~obj(void) { }; // dtor
private:
static int nr;
static bool initialized;
}

// file: obj.cpp
#include "obj.h"

// Waring: Static members need external definition!
int obj::nr;
// default value of static member:
bool obj::initialized=false;
Στον παραπάνω κώδικα βλέπουμε ένα παράδειγμα χρήσης στατικών μεταβλητών σε C++ class. Οι μεταβλητές nr, και initialized είναι ίδιες σε όλες τα στιγμιότυπα (instances) αντικειμένων από το class obj. Μάλιστα η μεταβλητή έχει αρχική μεταβλητή false, η οποία δεν ορίζεται μέσα στον ctor αλλά εξωτερικά.

20071116

C++: Example of class with ctor, increment operator (prefix and suffix) and ostream overloading.

// simple Int class with ctor, increment operator and ostream overload 
class Int{
public:
Int& operator++();
const Int operator++( int n );

Int(int i): _i(i) { };

friend ostream& operator <<(ostream& os, const Int &i);
private:
int _i;
};

// look difference between return values: Int& (in prefix)
Int& Int::operator++() {
_i++; // Handle case where no argument is passed.
return *this;
}

// and const Int (in postfix)
const Int Int::operator++( int n ) {
Int tmp(*this);

if( n != 0 )
for (int nr=0; nr<n; ++nr, ++(*this));
else
++(*this);

return tmp;
}

// overloading << operator for Int class
ostream& operator <<(ostream& os, const Int &i) {
os << i._i;
return os;
}

void main() {

Int gg(0);
cout << gg.operator++(25) << endl ; // Increment by 25 but shown 0
cout << gg << endl; // in next reference is shown as 25

// gg = 25
cout << gg++ << endl; // gg is 25. Only in the next reference will it be 26
cout << gg << endl; // gg is 26.
// gg = 26
cout << ++gg << endl; // ggia is immidiately 27
cout << gg << endl; // ggia is 27

return;
}
Link: Περισσότερα για την διαφορά prefix/suffix.

C++: difference between prefix and suffix increment / decrement.

  • As a prefix : i.e. when the operator precedes the variable (as in ++ i, where i is the integer variable)

If we write:

i1 = 10;
i2 = ++ i1;

This is the same as:

i1 = 10;
i1 = i1 + 1;
i2 = i1;

At the end of these steps the value of both i1 and i2 will be 11. When used as a prefix, the variable is first incremented and later assigned.

  • As a suffix: i.e. when the variable precedes the operator (as in i ++).

If we write:

i1 = 10;
i2 = i1 ++ ;

This is the same as writing:

i1 = 10;
i2 = i1;
i1 = i1 + 1;

At the end of these steps the value of i2 will be 10 and that of i1 will be 11. When used as a postfix, the variable value is first assigned and later incremented.

// suffix
int sum=5; // sum is 5
cout << sum++; // sum is 5. Only in the next reference to sum will it be 6
cout << " " << sum << endl; // sum is now 6

// prefix
sum=5; // sum is 5
cout<<++sum; // sum is immediately 6
cout<<" "<<sum; // sum is 6

Remember: When used as a prefix ( ++i ) compiler will first increment and then assign. When used as a suffix, assignment is done first and then incrementing is performed.

Link: C++ Operators - IV.

20071109

Visual Studio .NET 2005: Static library creation/usage.

Από το σύνδεσμο είναι οι παρακάτω πληροφορίες:

//---------------------------------------------------//

Walkthrough: Creating and Using a Static Library

In this walkthrough, you will create a static library (LIB) containing useful routines that can be used by other applications. Using static libraries is a great way to reuse code. Rather than re-implementing these routines in every program you create, you write them once and reference them from applications that need the functionality.

This walkthrough uses native C++. For a walkthrough using native C++ to create a dynamic link library (DLL), see Walkthrough: Creating and Using a Dynamic Link Library. For a walkthrough using Visual C++ that targets the Common Language Runtime, see Walkthrough: Creating and Using a Managed Assembly.

This walkthrough covers the following:

  • Creating a new static library project

  • Adding a class to the static library

  • Creating an application that references the static library

  • Using the functionality from the static library in the console application

  • Running the application

PrerequisitesPrerequisites

This topic assumes you understand the fundamentals of the C++ language.

To create a new static library project
  1. From the File menu, select New and then Project….

  2. From the Project types pane, under Visual C++, select Win32.

  3. From the Templates pane, select Win32 Console Application.

  4. Choose a name for the project, such as MathFuncsLib, and enter it in the Name field. Choose a name for the solution, such as StaticLibrary, and enter it in the Solution Name field.

  5. Press OK to start the Win32 application wizard. From the Overview page of the Win32 Application Wizard dialog, press Next.

  6. From the Application Settings page of the Win32 Application Wizard, under Application type, select Static library.

  7. From the Application Settings page of the Win32 Application Wizard, under Additional options, deselect Precompiled header.

  8. Press Finish to create the project.

To add a class to the static library
  1. To create a header file for a new class, from the Project menu, select Add New Item…. The Add New Item dialog will be displayed. From the Categories pane, under Visual C++, select Code. From the Templates pane, select Header File (.h). Choose a name for the header file, such as MathFuncsLib.h, and press Add. A blank file will be displayed.

  2. Add a simple class named MyMathFuncs to do common mathematical operations, such as addition, subtraction, multiplication, and division. The code should resemble the following:

    // MathFuncsLib.h

    namespace MathFuncs
    {
    class MyMathFuncs
    {
    public:
    // Returns a + b
    static double Add(double a, double b);

    // Returns a - b
    static double Subtract(double a, double b);

    // Returns a * b
    static double Multiply(double a, double b);

    // Returns a / b
    // Throws DivideByZeroException if b is 0
    static double Divide(double a, double b);
    };
    }

  3. To create a source file for a new class, from the Project menu, select Add New Item…. The Add New Item dialog will be displayed. From the Categories pane, under Visual C++, select Code. From the Templates pane, select C++ File (.cpp). Choose a name for the source file, such as MathFuncsLib.cpp, and press Add. A blank file will be displayed.


  4. Implement the functionality for MyMathFuncs in the source file. The code should resemble the following:

    // MathFuncsLib.cpp
    // compile with: /c /EHsc
    // post-build command: lib MathFuncsLib.obj

    #include "MathFuncsLib.h"

    #include <stdexcept>

    using namespace std;

    namespace MathFuncs
    {
    double MyMathFuncs::Add(double a, double b)
    {
    return a + b;
    }

    double MyMathFuncs::Subtract(double a, double b)
    {
    return a - b;
    }

    double MyMathFuncs::Multiply(double a, double b)
    {
    return a * b;
    }

    double MyMathFuncs::Divide(double a, double b)
    {
    if (b == 0)
    {
    throw new invalid_argument("b cannot be zero!");
    }

    return a / b;
    }
    }

  5. To build the project into a static library, from the Project menu, select MathFuncsLib Properties…. From the left pane, under Configuration Properties, select General. From the right pane, change the Configuration Type to Static Library (.lib). Press OK to save the changes.

    NoteNote

    If building from the command line, you must build the program in two steps. First, compile the code using Cl.exe with the /c compiler option (cl /c /EHsc MathFuncsLib.cpp). This will create an object file named MathFuncsLib.obj. For more information, see /c (Compile Without Linking). Second, link the code using the Library Manager Lib.exe (lib MathFuncsLib.obj). This will create the static library MathFuncsLib.lib. For more information on the Library Manager, see LIB Reference.


  6. Compile the static library by selecting Build Solution from the Build menu. This creates a static library that can be used by other programs.

To create an application that references the static library

  1. To create an application that will reference and use the static library that was just created, from the File menu, select New and then Project….


  2. From the Project types pane, under Visual C++, select Win32.


  3. From the Templates pane, select Win32 Console Application.


  4. Choose a name for the project, such as MyExecRefsLib, and enter it in the Name field. Next to Solution, select Add to Solution from the drop down list. This will add the new project to the same solution as the static library.


  5. Press OK to start the Win32 Application Wizard. From the Overview page of the Win32 Application Wizard dialog, press Next.


  6. From the Application Settings page of the Win32 Application Wizard, under Application type, select Console application.


  7. From the Application Settings page of the Win32 Application Wizard, under Additional options, deselect Precompiled header.


  8. Press Finish to create the project.

To use the functionality from the static library in the console application

  1. After you create a new Console Application, an empty program is created for you. The name for the source file will be the same as the name you chose for the project above. In this example, it is named MyExecRefsLib.cpp.


  2. To use the math routines that were created in the static library, you must reference it. To do this, select References… from the Project menu. From the Property Pages dialog, expand the Common Properties node and select References. Then select the Add New Reference… button. For more information on the References… dialog, see References, Common Properties, <Projectname> Property Pages Dialog Box.


  3. The Add Reference dialog is displayed. This dialog lists all the libraries that you can reference. The Project tab lists all the projects in the current solution and any libraries they contain. From the Projects tab, select MathFuncsLib. Then select OK. For more information on the Add Reference dialog, see Add Reference Dialog Box.


  4. To reference the header files of the static library, you must modify the include directories path. To do this, from the Property Pages dialog, expand the Configuration Properties node, then the C/C++ node, and select General. Next to Additional Include Directories, type in the path to the location of the MathFuncsLib.h header file.


  5. You can now use the MyMathFuncs class in this application. Replace the contents of MyExecRefsLib.cpp with the following code:

    // MyExecRefsLib.cpp
    // compile with: /EHsc /link MathFuncsLib.lib

    #include <iostream>

    #include "MathFuncsLib.h"

    using namespace std;

    int main()
    {
    double a = 7.4;
    int b = 99;

    cout << "a + b = " <<
    MathFuncs::MyMathFuncs::Add(a, b) << endl;
    cout << "a - b = " <<
    MathFuncs::MyMathFuncs::Subtract(a, b) << endl;
    cout << "a * b = " <<
    MathFuncs::MyMathFuncs::Multiply(a, b) << endl;
    cout << "a / b = " <<
    MathFuncs::MyMathFuncs::Divide(a, b) << endl;

    return 0;
    }

  6. Build the executable by selecting Build Solution from the Build menu.

To run the application

  1. Make sure MyExecRefsLib is selected as the default project. From the Solution Explorer, select MyExecRefsLib, and then select Set As StartUp Project from the Project menu.


  2. To run the project, select Start Without Debugging from the Debug menu. The output should look like this:

    a + b = 106.4
    a - b = -91.6
    a * b = 732.6
    a / b = 0.0747475
//---------------------------------------------------//

Η παραπάνω μεθοδολογία μας προτείνει να χρησιμοποιήσουμε μέσω του "Αdd Reference" το project με την βιβλιοθήκη static lib. Αν θέλουμε κατευθείαν να χρησιμοποιήσουμε την βιβλιοθήκη (lib) χωρίς να χρησιμοποιήσουμε το project πρέπει να ορίσουμε το directory όπου βρίσκεται η βιβλιοθήκη που φτιάξαμε. Υπάρχουν 2 εκδόσεις, η debug και η release έκδοση.. και αντίστοιχα ορίζουμε χειροκίνητα στα project properties:

Release έκδοση:

Debug έκδοση:

20071102

C++ Boost: Reading all the text files of directory and apply a substitution using a regular expression.

#include <fstream>
#include <string>
#include <sstream>
#include <iostream>
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/fstream.hpp>
#include <boost/regex.hpp>

using namespace boost::filesystem;
using namespace std;

// Apply Regular Expression + substitution
string process_str(string str, string regex, string substitution) {

cout << "applying regular expression.. " << regex << endl;

string result=string();

boost::regex reg(regex);

result=boost::regex_replace(str,reg,substitution);

return result;
}

// Read file fname and return its contents in string format
string load_data_in_str(string fname) {
// ifstream fIn;
// Error 1 error C2872: 'ifstream' : ambiguous symbol
// Because ifstream is defined by 2 namespaces:
// namespace std and boost::filesystem (!)
// Use either std::ifstream fIn; either boost::filesystem::ifstream fIn;

// If I use boost::filesystem::ifstream
boost::filesystem::ifstream fIn;

// Obj fIn can has as argument string fname:
// fIn.open(fname,std::ios::in);
// either obj boost::filesystem::path:
// fIn.open(path(fname),std::ios::in);
// But for comparibility with std::ifstream I use:
fIn.open(fname.c_str(),std::ios::in);

if (!fIn) {
cerr << "string load_data_in_str(string fname)" << endl;
cerr << "Error reading the file: " << fname << endl;
getchar();
exit(0);
}

string l;

stringstream ss;

ss << fIn.rdbuf();

return ss.str();
}

// Write to filename fname contents of string data (with default the overwrite: append=false)
void write_str_in_file(string fname, string data, bool append=false) {
// For the same reason as in function string load_data_in_str(string fname)
// I choose with lib I will use from namespaces: (boost::filesystem:: vs std::).
boost::filesystem::ofstream fOut;

if (append)
fOut.open(fname.c_str(),ios::app);
else
fOut.open(fname.c_str(),ios::out);

if (!fOut) {
cerr << "void write_str_in_file(string fname, string data, bool append)" << endl;
cerr << "Error writing to file: " << fname << endl;
getchar();
exit(0);
}

fOut << data;

fOut.close();
}

int main(int argc, char* argv[]) {

if (argc!=5) {
cerr << "Usage: " << argv[0]
<< " [ files dir ] [ reg ex ] [ substritution ] [ out file dir ]" << endl;
cerr << "Press <enter> to continue.." << endl;
getchar();
return (EXIT_FAILURE);
}

// template <class Path> Path system_complete(const Path& p);

// Effects: Composes a complete path from p, using the same rules
// used by the operating system to resolve a path passed as the
// filename argument to standard library open functions.

// Returns: The composed path.

// Postcondition: For the returned path, rp, rp.is_complete() is true.

// Throws: If p.empty().

// Returns: The composed path.
// [Note: For POSIX, system_complete(p) has the same semantics as complete(p, current_path()).

// For Windows, system_complete(p) has the same semantics as complete(ph, current_path())
// if p.is_complete() || !p.has_root_name() or p and base have the same root_name().
// Otherwise it acts like complete(p, kinky), where kinky is the current directory for
// the p.root_name() drive. This will be the current directory of that drive the last
// time it was set, and thus may be residue left over from a prior program run by the
// command processor! Although these semantics are often useful, they are also very error-prone.


path InputPath=system_complete(path(argv[1],native));

// in #include <stdlib.h> are defined EXIT_FAILURE and EXIT_SUCCESS

if (!exists(InputPath)) {
cerr << "Error: the directoty " << InputPath
<< " does not exist." << endl;
return (EXIT_FAILURE);
}

if (!is_directory(InputPath)) {
cout << InputPath << " is not a directory!" << endl;
return (EXIT_SUCCESS);
}

path OutputPath=system_complete(path(argv[4],native));

if (!exists(OutputPath)) {
cerr << "Error: the directoty " << OutputPath
<< " does not exist." << endl;
return (EXIT_FAILURE);
}

if (!is_directory(OutputPath)) {
cout << InputPath << " is not a directory!" << endl;
return (EXIT_SUCCESS);
}
directory_iterator end;
for (directory_iterator it(InputPath); it!= end; ++it) {
cout << it->leaf() << endl;
cout << it->string();
string load_txt;
if (is_directory(*it))
cout << " (dir)";
else {
// Read file into the string load_txt
load_txt=load_data_in_str(it->string());
// Substitute the match of regular expression argv[2]
// with the text of substitution argv[3].
load_txt=process_str(load_txt, argv[2], argv[3]);
/// write_str_in_file(OutputPath.directory_string()+(it->leaf()),load_txt);

// basic_path& operator/=(const basic_path& rhs);
// Effects: The path stored in rhs is appended to the stored path.

// The following function as we read from documenation @ www.boost.org
// http://www.boost.org/libs/filesystem/doc/tr2_proposal.html#basic_path-observers
// path(OutputPath)/=path(it->leaf())
// Gets OutputPath = OutputPath + / + path(it->leaf());
// It concatenates path + filename.
// At the end with .string() we convert to string in order to pass it as argument
write_str_in_file((path(OutputPath)/=path(it->leaf())).string(),load_txt);

}
cout << endl;
}

getchar();

return (EXIT_SUCCESS);
}

eggs.in.art (my non-technical blog)