Sunday, April 01, 2007

String container class on Turbo C++

Update: This class has been heavily updated. This now even overloads the global ostream << iString and istream >> iString operators so that direct input/output through cout/cin (eg. cin >> iString and cout << iString) is possible. It has been heavily updated since it's first release. Upgradation is strongly recommended. See download page for more details.

Note: You are strongly advised to use the C++ string class shipped with your compiler if it has STL. If it does not, try using third partly STLs, like STL Port. If THAT doesn't work, then go in for this. Oh, and I've already tried everything for TurboC++, in case you're wondering. It's so old that nothing works on it. This has been made specifically for TurboC++.

The default string container class that ships with TurboC++ doesn't compile. Me being so used to the class, I just couldn't switch to using arrays of characters... So, well, I decided to create something similar myself. Of course, the trouble is, I can't modify cin and cout, so you'll have to use some workarounds when working with I/O. We'll come to that later, anyway.

For those who don't know what a string container class is, let's look at an example. Consider an array of characters. The array size is fixed. You'll have to create and array big enough to hold the largest value that can be inputted by the user. The trouble with this is that if the string is smaller, the rest of the space is wasted. Now, if you choose a smaller array, it can result in a buffer overflow. The solution is using dynamic memory allocation to create a class that does everything automatically, including memory allocation in such a way that the string "just fits". Consider the following piece of code:

char a[100]; strcpy(a,"Hello");

Around 94 bytes are wasted. A much simpler way is using the String container class. Consider the following code:

string a; a="hello";

Here, the memory occupied by a will be exactly 6 bytes. Now, let's say you have two strings and you want to concatenate them. Normally, you would

char a[100]; char b[50]; strcpy(a,"Some text you hope is less than (100-(size of b))"); strcpy(b,"Some more text. skjhgfkjhgsdkhldfk <---- some more text."); strcat(a,b);

If a is not big enough to hold a AND b, it will result in buffer overflow, resulting in what most programmers hope is an instant crash (otherwise, it can mess up the internals and crash a long time later). A much simpler code:

string a,b,c; a="Some text that can be of any size, limited to the max memory you have";
b="Some more text. skjhgfkjhgsdkhldfk <---- some more text.";
c=a+b; // c becomes the value of a followed by value of b
/* OR */ a+=b; // a becomes value of a followed by value of b

Note that here memory is automatically managed. You need not worry about how memory is allocated or buffer overflows or anything.

This class has been defined in ANSI C++, but is not properly implemented in TurboC++. That's why I created my own class. It can be downloaded from here. There's a huge difference between the standard string container class and this one, though:

  1. It is called iString instead of string. This is because I don't want to confuse string with my own implementation.

  2. Many of the standard C++ string functions haven't been declared. This is because I didn't have enough time. However, it can use the standard C string functions (like strcpy and stuff) provided it is passed to the functions as -stringName instead of stringName. Note the preceding hyphen '-'. We'll come back to it later.

  3. Since I can't modify cin and cout, you cant directly I/O these strings. However, there's a workaround. For outputting, use -stringName (note the hyphen '-'). For inputting, declare a temporary array of characters to store the string and then set the string as the array. For example:

    char *buffer; // declare buffer as a pointer buffer=new char[128]; // buffer is an array of 128 characters // The above two lines are almost equivalent to "char buffer[128];" iString myString; // myString is an object of the class iString cin.getline(buffer, 127); // get upto newline or 127 characters, whichever comes first myString=buffer; // set myString as the value of buffer, only upto what is inputted // ie. get upto first '\0' and store it in myString. rest of the buffer is not read delete [] buffer; // we dont need the buffer anymore, so free the memory cout << -myString; // note the hyphen '-'. that's the only difference here.

    Update: Created a function to directly input this string. The function requires getchar(), for which it automatically includes stdio.h if it has not been included. See download page for more details.

Now, the reason why you have to use these workarounds. The thing is, cin and cout are predefined classes. They input and output predefined datatypes, which includes integers, floating point numbers, characters, arrays of characters and strings (the container class). They do a different thing for int, a different thing for float, a different thing for char and so on. Now, since iString wasn't defined in cin and cout, you'll have to convert them to something more recognisable by them. The - (hyphen) before the object signifies the value of the string, as an array of characters, instead of an iString. While inputting, you write the data into a temporary array of characters, and then copy it from the array into the string.

Similarly, wherever you have to use the string as an array of characters, just put a hyphen '-' before it. Like strcmp(-string1, -string2) or printf("%s", -string). However, note that you wont be able to modify the string using the hyphen approach. The only way to modify the string is using = (equal to), += (append) and * (read input) operators and their respective methods. Oh, and you needn't use the hyphen when accessing a single element at a posititon. You can directly do string[position] instead of -string[position].

4 comments:

Anonymous said...

nice post. thanks.

Anonymous said...

i actually adore your writing type, very exciting.
don't give up and keep creating due to the fact it simply worth to read it.
looking forward to browse through more of your current web content, kind regards :)

Anonymous said...

Genial fill someone in on and this post helped me alot in my college assignement. Gratefulness you seeking your information.

Anonymous said...

top [url=http://www.c-online-casino.co.uk/]online casino[/url] brake the latest [url=http://www.casinolasvegass.com/]casino online[/url] unshackled no deposit hand-out at the foremost [url=http://www.baywatchcasino.com/]no deposit gratuity
[/url].