Useful Functions - Part 2

◀ Useful Functions - Part 1▶ A List of Traps and Tips
Amazon Let's look at more useful utility functions. They include functions to tell time, to pause for some time, to convert from string to number and vice versa, to tokenize a string, and to output invisible characters!

Show Time
Sometimes you would like to know how long a program runs. In this situation, you can certainly use the following code to achieve this purpose.
#include<ctime>  /* or <time.h> */

clock_t start = clock(); 		
/* then the program runs... */
.
.
.
/* program ends here; now output how much time the program has run */
cout << (float)(clock() - start) / CLOCKS_PER_SEC << " seconds\n";

Pause For Some Time
Sometimes you would like your program to halt for some time. Maybe the output fills the screen and you want it to pause for ten seconds, or maybe you write a game in which the user needs to respond within a certain amount of time. In these situations, a function that pauses for some time will be necessary.

A crude function that pauses the program for some time is by using a for loop. Here’s the sample function:
void pauses(){
  int pause = 1000000000;
  for(int i=0; i<pause; i++)
    ;
}
This function pauses for about seven seconds on my machine. The main advantage of using this approach is that it is very easy to write and to understand. The disadvantage is that you have no explicit control over how long it pauses for. The next function will be much better because you can control how long it pauses for.
#include<ctime>  /* or <time.h> for clock() and clock_t */
void pauses2(int sec){
	clock_t start = clock(); 
	while((float)(clock() - start) / CLOCKS_PER_SEC < sec)
		;
}

The bad thing about this solution is it'll quickly drain your CPU resources!
Here is another version, but your platform must support the sleep system call.
void pauses3(string sec){
	string s = "sleep "+sec;
	system(s.c_str());
}

Conversion Between String and Numbers
The header <stdlib.h> provides the following functions for number conversion:
  • double atof(const char *s): converts s to double
  • int atoi(const char *s): converts s to int
  • long atol(const char *s): converts s to long
Note that all the above functions have the common property that if the given string contains characters other than numbers, they still return some value; they don’t crash. They also work with negative values. Conversions to string from double, int, and long may need to be written by you.

The following function, dtoa(), converts a double or int to a string. It also works with negative values.
int getnod(int a){
	int t=1;
	while((a/=10)!=0)
		t++;
	return t;
}
bool allZeros(string s){
	for(int i=0; i<s.length(); i++)
		if(s[i]!=\'0\')
			return false;
	return true;
}
string dtoa(double val){
	char *buffer;
	string bufs;
	int precision = 6;
	int decimal, sign, i;

	buffer = fcvt(val, precision, &decimal, &sign);
	bufs+=buffer;

	if(decimal<=0){
		bufs.insert(0,"0.");
		for(i=0;i>decimal;i--)
			bufs.insert(2,"0");
	}
	else{
		if(allZeros(bufs.substr(getnod((int)val))))
			bufs=bufs.substr(0,getnod((int)val));
		else
			bufs.insert(getnod((int)val),".");
	}
	if(sign==0)
		return bufs;
	return "-"+bufs;
}

Tokenize a String
This function is one of the most useful functions I have ever written. It accepts a string of anything, including spaces and tabs, then returns a vector that contains individual words in that string. You can include as many spaces or tabs before, after the string and even between any two words in the string.

This function will ignore all the spaces and retrieve individual words. This function is useful in many ways. For example, you may want to keep track of information in the form of a string of data. Then you can use this function to retrieve individual items.

Another example is that maybe you expect user to give you many data items with a space being the delimiter. Obviously human is error-prone and may enter more than 1 space between 2 data items or even enter tabs. In those situations, using this function to process those data is a good idea. By the way, this function is already covered in Chapter 12.9.
#include <vector>
/*
precondition: s contains tokens separated by unprintable characters
postcondition: returns a vector that contains all tokens of s
*/
vector<string> tokenize(string s){
	int i,j;
	vector<string> vs;
	int slen=s.length();

	j=0;
/* use a while loop to retrieve all tokens */
	while(j<slen){
/* skip all unprintable characters until a printable character is reached */
		while(!isgraph(s[j++]) && j<slen)
			;
		if(j>=slen) return vs;
		i=j-1;
/* take all characters until an unprintable character is reached */
		while(isgraph(s[j++]) && j<slen)
			;
/* store it in the vector */
		if(j>=slen) j++;
		vs.push_back(s.substr(i,j-i-1));
	}
/* return the vector */
	return vs;
}

Output Invisible Characters
Sometimes in debugging your program, you wish to see what a string or a char really contains but it may contain invisible characters such as newline, carriage return, and space. As an example, you are writing an HTTP client who needs to send an HTTP request to an HTTP server in order to retrieve some document. The HTTP request needs to conform to rules governing interactions between an HTTP client and an HTTP server.

In such a situation, you need to make sure the request your client sends is valid. Here are some simple functions to achieve this end:
void examineChar(char c){
	if(c==\'\n\')
		cout<<"\\n";
	else if(c==\'\r\')
		cout<<"\\r";
	else if(c==\'\b\')
		cout<<"\\b";
	else if(c==\'\t\')
		cout<<"\\t";
	else if(c==\'\a\')
		cout<<"\\a";
	else if(c==\'\v\')
		cout<<"\\v";
	else if(c==\'\0\')
		cout<<"\\0";
	else
		cout<<c;
}

void examineCharStar(char *cs){
	int i;
	for(i=0;i<strlen(cs);i++)
		examineChar(cs[i]);
}

void examineString(string s){
	int i;
	if(s!="")
	    for(i=0;i<s.length();i++)
			examineChar(s[i]);
}
Note that a string can be “” but a char cannot be ‘’.

Next let’s look at a list of common traps and tips!
◀ Useful Functions - Part 1▶ A List of Traps and Tips

fShare
Questions? Let me know!