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 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192
|
\section{BALL Strings}
BALL provides a heavy-weight \class{String} class that has been designed
to provide a wealth of functionality using a simple and consistent syntax.
In general, you should avoid using {\tt const char*} or STL string when using
BALL, although they are compatible to each other. You can easily convert BALL
strings to char pointers (using the {\tt c\_str()} method) and automatically
convert char pointers to BALL strings.
This part of the tutorial will give a short introduction to the wealthy
functionality of BALL strings. For complete information refer to the BALL
Reference Manual~\cite{BALL-RM}.
\subsection{String Operations}
There are useful operations possible with BALL strings. Let us start with a
very basic one, concatenation. The following code snippet will concatenate two
BALL strings:
\begin{lstlisting}{}
String A("Concat");
String B("enate");
String C = A + B;
\end{lstlisting}
But concatenation is also defined with STL strings and even standard C
strings, \ie {\tt char*}, as operands:
\begin{lstlisting}{}
string A("Concat");
char* B = "enate";
String C = A + B;
\end{lstlisting}
\noindent
Another very useful operation is swapping two strings:
\begin{lstlisting}{}
String A("Swap");
String B("swaP");
A.swap(B);
\end{lstlisting}
\noindent
Something we might also use very often is reversing a string:
\begin{lstlisting}{}
String A("Swap");
A.reverse();
\end{lstlisting}
\noindent
And finally, it is even possible to substitute parts of a string with another
\class{String} by using the \method{substitute} method:
\begin{lstlisting}{}
String A("Please replace REPLACE with something else.");
String B("REPLACE");
String C("SOMETHING ELSE");
A.substitute(B, C);
\end{lstlisting}
\subsection{Conversion}
BALL strings are featured with many conversion mechanisms. Converting other
types to a BALL string is done by using a constructor. Let us first construct
a string from some basic C types:
\begin{lstlisting}{}
char c_char = 'B';
int c_int = 1;
float c_float = 2.99792458;
String A(c_char);
String B(c_int);
String C(c_float);
\end{lstlisting}
There are many other simple types supported, like {\tt unsigned int}, {\tt
double}, etc. Refer to the reference manual for further information.
How do we make an {\tt int} out of a BALL string? Or a {\tt char}? That's
equally easy. We only need to call the explicit conversion method. All those
methods are named {\tt toType}, where {\tt Type} is the type you want to
convert to. Have a look at the following example:
\begin{lstlisting}{}
String i_wanna_be_an_int("4711");
String i_wanna_be_a_char("A");
String i_wanna_be_a_double("6.0221e23");
int i_am_an_int = i_wanna_be_an_int.toInt();
char i_am_a_char = i_wanna_be_a_char.toChar();
double i_am_a_double = i_wanna_be_a_double.toDouble();
\end{lstlisting}
\subsection{Predicates}
BALL strings provide many predicates that can be used for determining special
properties. One can find out whether a \class{String} contains a certain
substring, starts with a special prefix, ends with a suffix, consists only of
letters or is simply a floating point number. The following code snippet will
give you some idea of the power of the predicates.
\begin{lstlisting}{}
String T("This STRING does not start with PREFIX");
cout << "String is empty? " << T.isEmpty()
<< endl;
cout << "Has prefix \"PREFIX\"? " << T.hasPrefix("PREFIX")
<< endl;
cout << "Contains \"PREFIX\"? " << T.hasSubstring("PREFIX")
<< endl;
cout << "Contains only letters? " << T.isAlpha()
<< endl;
\end{lstlisting}
\noindent
We will get the following output:
\begin{lstlisting}{}
String is empty? 0
Has prefix "PREFIX"? 0
Contains substring "PREFIX"? 1
Contains only letters? 1
\end{lstlisting}
\subsection{Comparing Strings}
Commonly one often wants to compare strings, which is a pain with C type
character fields. BALL strings provide you with a simple interface and rich
functionality. Let's first have a look at equality tests. Note that you are
not limited to BALL strings for those comparisons, but can use C strings
as arguments to all those operations:
\begin{lstlisting}{}
String test_string("Compare me.");
String another_test_string("Blah.");
char* test_C_string = "No match.";
cout << test_string.compare(another_test_string) << endl;
cout << test_string.compare(test_C_string) << endl;
cout << test_string == test_string << endl;
cout << test_string != "No, this is not equal." << endl;
\end{lstlisting}
You can also check whether a string is lexicographically less than another
one:
\begin{lstlisting}{}
cout << test_string < another_test_string << endl;
\end{lstlisting}
And finally it is even possible to limit the comparison to a certain area of
a string by defining the start index and the length of the segment:
\begin{lstlisting}{}
Index start_index = 9;
Size length = 2;
cout << test_string.compare("me", start_index, length) << endl;
\end{lstlisting}
\subsection{Stream and Field Operations}
Everyone familiar with measurement data processing encountered the problem of
getting data fields out of lines containing several values of data. Quite
often interpreter languages like awk or perl are used for such tasks. The
disadvantage of using such tools obviously is that you cannot integrate such
languages easily into a \CPP program. The BALL development team was also
frequently confronted with such problems. Resultingly, BALL strings provide
methods to extract fields from strings.
\begin{lstlisting}{}
String data = "1 2 3 4.567 8 blah";
cout << "Line contains " << data.countFields()
<< " values" << endl;
cout << "The data at index 5 is " << data.getField(5) << endl;
\end{lstlisting}
\noindent
The code above should print the number 8. Sometimes log files contain quoted
data. You can even handle such lines by using the field functions for quoted
entries:
\begin{lstlisting}{}
String data = "1 2 3 4.567 \"8 blah\"";
cout << "Line contains " << data.countFieldsQuoted()
<< " values" << endl;
cout << "The data at index 5 is " << data.getFieldQuoted(5)
<< endl;
\end{lstlisting}
\noindent
The code above should print the number "8 blah".
Additionally BALL strings know how to get single lines from a stream. So, if
you want to read and analyze a log file, open it, read the sinlge lines and
get the values you want:
\begin{lstlisting}{}
istream is;
Index index = 5;
String line = getline(is)
String value = line.getField(index)
\end{lstlisting}{}
|