Showing posts with label C. Show all posts
Showing posts with label C. Show all posts

Saturday, May 29, 2010

TYPE CASTING C/C++

Type Casting



Converting an expression of a given type into another type is known as type-casting

Implicit conversion

Implicit conversions do not require any operator. They are automatically performed when a value is copied to a compatible type. For example:
short a=2000;
int b;
b=a;
Here, the value of a has been promoted from short to int and we have not had to specify any type-casting operator. This is known as a standard conversion. Standard conversions affect fundamental data types, and allow conversions such as the conversions between numerical types (short to int, int to float, double to int...), to or from bool, and some pointer conversions. Some of these conversions may imply a loss of precision, which the compiler can signal with a warning. This can be avoided with an explicit conversion.
Implicit conversions also include constructor or operator conversions, which affect classes that include specific constructors or operator functions to perform conversions. For example:
class A {};
class B { public: B (A a) {} };
 
A a;
B b=a;
Here, a implicit conversion happened between objects of class A and class B, because B has a constructor that takes an object of class A as parameter. Therefore implicit conversions from A to B are allowed.

Explicit conversion

C++ is a strong-typed language. Many conversions, specially those that imply a different interpretation of the value, require an explicit conversion. We have already seen two notations for explicit type conversion: functional and c-like casting:
short a=2000;
int b;
b = (int) a;    // c-like cast notation
b = int (a);    // functional notation 
The functionality of these explicit conversion operators is enough for most needs with fundamental data types. However, these operators can be applied indiscriminately on classes and pointers to classes, which can lead to code that while being syntactically correct can cause runtime errors. For example, the following code is syntactically correct:
// class type-casting
#include 
using namespace std;
 
class CDummy {
    float i,j;
};
 
class CAddition {
        int x,y;
  public:
        CAddition (int a, int b) { x=a; y=b; }
        int result() { return x+y;}
};
 
int main () {
  CDummy d;
  CAddition * padd;
  padd = (CAddition*) &d;
  cout << padd->result();
  return 0;
}
 
The program declares a pointer to CAddition, but then it assigns to it a reference to an object of another incompatible type using explicit type-casting:
padd = (CAddition*) &d;
Traditional explicit type-casting allows to convert any pointer into any other pointer type, independently of the types they point to. The subsequent call to member result will produce either a run-time error or a unexpected result.
In order to control these types of conversions between classes, we have four specific casting operators: dynamic_cast, reinterpret_cast, static_cast and const_cast. Their format is to follow the new type enclosed between angle-brackets (<>) and immediately after, the expression to be converted between parentheses.
dynamic_cast (expression)
reinterpret_cast (expression)
static_cast (expression)
const_cast (expression)

The traditional type-casting equivalents to these expressions would be:

(new_type) expression
new_type (expression)

but each one with its own special characteristics:

dynamic_cast

dynamic_cast can be used only with pointers and references to objects. Its purpose is to ensure that the result of the type conversion is a valid complete object of the requested class.
Therefore, dynamic_cast is always successful when we cast a class to one of its base classes:
class CBase { };
class CDerived: public CBase { };
 
CBase b; CBase* pb;
CDerived d; CDerived* pd;
 
pb = dynamic_cast(&d);     // ok: derived-to-base
pd = dynamic_cast(&b);  // wrong: base-to-derived 
The second conversion in this piece of code would produce a compilation error since base-to-derived conversions are not allowed with dynamic_cast unless the base class is polymorphic.
When a class is polymorphic, dynamic_cast performs a special checking during runtime to ensure that the expression yields a valid complete object of the requested class:
// dynamic_cast
#include 
#include 
using namespace std;
 
class CBase { virtual void dummy() {} };
class CDerived: public CBase { int a; };
 
int main () {
  try {
    CBase * pba = new CDerived;
    CBase * pbb = new CBase;
    CDerived * pd;
 
    pd = dynamic_cast(pba);
    if (pd==0) cout << "Null pointer on first type-cast" << endl;
 
    pd = dynamic_cast(pbb);
    if (pd==0) cout << "Null pointer on second type-cast" << endl;
 
  } catch (exception& e) {cout << "Exception: " << e.what();}
  return 0;
}
Null pointer on second type-cast

Compatibility note: dynamic_cast requires the Run-Time Type Information (RTTI) to keep track of dynamic types. Some compilers support this feature as an option which is disabled by default. This must be enabled for runtime type checking using dynamic_cast to work properly.
The code tries to perform two dynamic casts from pointer objects of type CBase* (pba and pbb) to a pointer object of type CDerived*, but only the first one is successful. Notice their respective initializations:
CBase * pba = new CDerived;
CBase * pbb = new CBase;
Even though both are pointers of type CBase*, pba points to an object of type CDerived, while pbb points to an object of type CBase. Thus, when their respective type-castings are performed using dynamic_cast, pba is pointing to a full object of class CDerived, whereas pbb is pointing to an object of class CBase, which is an incomplete object of class CDerived.

When
dynamic_cast cannot cast a pointer because it is not a complete object of the required class -as in the second conversion in the previous example- it returns a null pointer to indicate the failure. If dynamic_cast is used to convert to a reference type and the conversion is not possible, an exception of type bad_cast is thrown instead.
dynamic_cast can also cast null pointers even between pointers to unrelated classes, and can also cast pointers of any type to void pointers (void*).

static_cast

static_cast can perform conversions between pointers to related classes, not only from the derived class to its base, but also from a base class to its derived. This ensures that at least the classes are compatible if the proper object is converted, but no safety check is performed during runtime to check if the object being converted is in fact a full object of the destination type. Therefore, it is up to the programmer to ensure that the conversion is safe. On the other side, the overhead of the type-safety checks of dynamic_cast is avoided.
class CBase {};
class CDerived: public CBase {};
CBase * a = new CBase;
CDerived * b = static_cast(a);
This would be valid, although b would point to an incomplete object of the class and could lead to runtime errors if dereferenced.
static_cast can also be used to perform any other non-pointer conversion that could also be performed implicitly, like for example standard conversion between fundamental types:
double d=3.14159265;
int i = static_cast<int>(d); 
Or any conversion between classes with explicit constructors or operator functions as described in "implicit conversions" above.

reinterpret_cast

reinterpret_cast converts any pointer type to any other pointer type, even of unrelated classes. The operation result is a simple binary copy of the value from one pointer to the other. All pointer conversions are allowed: neither the content pointed nor the pointer type itself is checked.
It can also cast pointers to or from integer types. The format in which this integer value represents a pointer is platform-specific. The only guarantee is that a pointer cast to an integer type large enough to fully contain it, is granted to be able to be cast back to a valid pointer.
The conversions that can be performed by reinterpret_cast but not by static_cast have no specific uses in C++ are low-level operations, whose interpretation results in code which is generally system-specific, and thus non-portable. For example:
class A {};
class B {};
A * a = new A;
B * b = reinterpret_cast(a);
This is valid C++ code, although it does not make much sense, since now we have a pointer that points to an object of an incompatible class, and thus dereferencing it is unsafe.

const_cast

This type of casting manipulates the constness of an object, either to be set or to be removed. For example, in order to pass a const argument to a function that expects a non-constant parameter:
// const_cast
#include 
using namespace std;
 
void print (char * str)
{
  cout << str << endl;
}
 
int main () {
  const char * c = "sample text";
  print ( const_cast<char *> (c) );
  return 0;
}
sample text

typeid

typeid allows to check the type of an expression:
typeid (expression)
This operator returns a reference to a constant object of type type_info that is defined in the standard header file . This returned value can be compared with another one using operators == and != or can serve to obtain a null-terminated character sequence representing the data type or class name by using its name() member.
// typeid
#include 
#include 
using namespace std;
 
int main () {
  int * a,b;
  a=0; b=0;
  if (typeid(a) != typeid(b))
  {
    cout << "a and b are of different types:\n";
    cout << "a is: " << typeid(a).name() << '\n';
    cout << "b is: " << typeid(b).name() << '\n';
  }
  return 0;
}
a and b are of different types:
a is: int *
b is: int  
When typeid is applied to classes typeid uses the RTTI to keep track of the type of dynamic objects. When typeid is applied to an expression whose type is a polymorphic class, the result is the type of the most derived complete object:
// typeid, polymorphic class
#include 
#include 
#include 
using namespace std;
 
class CBase { virtual void f(){} };
class CDerived : public CBase {};
 
int main () {
  try {
    CBase* a = new CBase;
    CBase* b = new CDerived;
    cout << "a is: " << typeid(a).name() << '\n';
    cout << "b is: " << typeid(b).name() << '\n';
    cout << "*a is: " << typeid(*a).name() << '\n';
    cout << "*b is: " << typeid(*b).name() << '\n';
  } catch (exception& e) { cout << "Exception: " << e.what() << endl; }
  return 0;
}
a is: class CBase *
b is: class CBase *
*a is: class CBase
*b is: class CDerived
Notice how the type that typeid considers for pointers is the pointer type itself (both a and b are of type class CBase *). However, when typeid is applied to objects (like *a and *b) typeid yields their dynamic type (i.e. the type of their most derived complete object).
If the type typeid evaluates is a pointer preceded by the dereference operator (*), and this pointer has a null value, typeid throws a bad_typeid exception.

GOOD EXAMPLE OF CALL BY REFERENCE VS CALL BY VALUE

How many times you get in a situation and think what to use in your function arguments- Call By Reference Or Call By Value?

This ain't tricky et al if you remember all basic simple thing i.e. In call by value, a function call passes arguments by value. The called function creates a new set of variables and copies the values of arguments into them. The function does not have access to the actual variables in the calling program and can only work on the copies of values. This mechanism is fine if the function does not need to alter the values of the original variables in the calling program. But, there may arise situation where we would like to change the values of variables in the calling program. One good example is Bubble Sort, we compare the two adjacent elements in the list and interchange their values if the first element is greater than the second. Now if the function is used for bubble sort, then it should be able to alter the values of variables in the calling function as well, which is not possible if the call by value method is used.
I'm sure this will help you remember the difference for your life now :)

Tuesday, May 25, 2010

INLINE FUNCTIONS VS MACROS

INLINE FUNCTION VS MACROS: the old battle :)

I'm sure sometime or the other you might have had this question popping out of your mind-
"I’m confused about the use of inline functions and macros.What is the difference between them?"


Well the answer is simple->


Inline functions are similar to macros because they both are expanded at compile time, but the macros are expanded by the preprocessor, while inline functions are parsed by the compiler. There are several important differences:
  • Inline functions follow all the protocols of type safety enforced on normal functions.
  • Inline functions are specified using the same syntax as any other function except that they include the inline keyword in the function declaration.
  • Expressions passed as arguments to inline functions are evaluated once. In some cases, expressions passed as arguments to macros can be evaluated more than once.


Now the BIG QUESTION-
When should I use macro and when inline functions?


Besides the difference already pointed out, you also must have in mind that because macros are expanded at pre-compile time, you cannot use them for debugging, but you can use inline functions. This is one important judging factor, isn't it?

Tuesday, May 18, 2010

Stack unwinding?

What do you mean by Stack unwinding? 
It is a process during exception handling when the destructor is called for all local objects between the place where the exception was thrown and where it is caught.

What is a dangling pointer?

What is a dangling pointer? 
A dangling pointer arises when you use the address of an object after
its lifetime is over. This may occur in situations like returning
addresses of the automatic variables from a function or using the
address of the memory block after it is freed. The following
code snippet shows this:

class Sample
{
public:
int *ptr;
Sample(int i)
{
ptr = new int(i);
}

~Sample()
{
delete ptr;
}
void PrintVal()
{
cout << "The value is " << *ptr;
}
};

void SomeFunc(Sample x)
{
cout << "Say i am in someFunc " << endl;
}

int main()
{
Sample s1 = 10;
SomeFunc(s1);
s1.PrintVal();
}

In the above example when PrintVal() function is
called it is called by the pointer that has been freed by the
destructor in SomeFunc.

Monday, February 1, 2010

puts() Vs fputs()


Write string to stdout puts():
Writes the C string pointed by str to stdout and appends a newline character ('\n').
The function begins copying from the address specified (str) until it reaches the terminating null character ('\0'). This final null-character is not copied to stdout.

Using fputs(str,stdout) instead, performs the same operation as puts(str) but without appending the newline character at the end.

/* puts example : hello world! */
#include 

int main ()
{
  char string [] = "Hello world!";
  puts (string);
}

Return Value

On success, a non-negative value is returned.
On error, the function returns EOF.


Write string to stream fputs():
Writes the string pointed by str to the stream.
The function begins copying from the address specified (str) until it reaches the terminating null character ('\0'). This final null-character is not copied to the stream.
/* fputs example */
#include < stdio.h >

int main ()
{
   FILE * pFile;
   char sentence [256];

   printf ("Enter sentence to append: ");
   fgets (sentence,255,stdin);
   pFile = fopen ("mylog.txt","a");
   fputs (sentence,pFile);
   fclose (pFile);
   return 0;
}

Return Value

On success, a non-negative value is returned. On error, the function returns EOF.


gets() Vs fgets()


Get string from stdin
Reads characters from stdin and stores them as a string into str until a newline character ('\n') or the End-of-File is reached.
The ending newline character ('\n') is not included in the string.
A null character ('\0') is automatically appended after the last character copied to str to signal the end of the C string.
Notice that gets does not behave exactly as fgets does with stdin as argument: First, the ending newline character is not included with gets while with fgets it is. And second, gets does not let you specify a limit on how many characters are to be read, so you must be careful with the size of the array pointed by str to avoid buffer overflows.

Return Value

On success, the function returns the same str parameter.
If the End-of-File is encountered and no characters have been read, the contents of str remain unchanged and a null pointer is returnes.
If an error occurs, a null pointer is returned.
Use either ferror or feof to check whether an error happened or the End-of-File was reached.

/* gets example */
#include < stdio.h >

int main()
{
  char string [256];
  printf ("Insert your full address: ");
  gets (string);
  printf ("Your address is: %s\n",string);
  return 0;
}

fgets():
Reads characters from stream and stores them as a C string into str until (num-1) characters have been read or either a newline or a the End-of-File is reached, whichever comes first. A newline character makes fgets stop reading, but it is considered a valid character and therefore it is included in the string copied to str. A null character is automatically appended in str after the characters read to signal the end of the C string.

Return Value

On success, a non-negative value is returned. On error, the function returns EOF.
/* fgets exmaple */
#include < stdio.h >

int main()
{
   FILE * pFile;
   char mystring [100];

   pFile = fopen ("myfile.txt" , "r");
   if (pFile == NULL) perror ("Error opening file");
   else {
     fgets (mystring , 100 , pFile);
     puts (mystring);
     fclose (pFile);
   }
   return 0;
}

Wednesday, January 6, 2010

Why a programmer need to take care of freeing the memory?

Why a programmer need to take care of freeing the memory?


If you have a subroutine like this

int subroutine(int param){
char example_variable [200];

whatever the routine does....

}

is necessary to release the memory used by the variable example_variable??? or is this automatically released when the variable get out of scope???


variables are created in different spaces within a program.
the example[100] variable would be created within a stack which would be deleted as soon as the program terminates so the programmer doesn't need to take care of freeing that. but any address dynamically obtained is obtained from the heap which is a pool of memory of all the programs running and not specific to one. so a programmer needs to take care of freeing or deleting (basically returning the space back to the pool) when the purpose of that variable is served and no longer required.

operator new[] and delete[] C/C++

// operator delete[] example
#include < iostream >
#include < new >
using namespace std;

struct myclass {
myclass() {cout <<"myclass constructed\n";}
~myclass() {cout <<"myclass destroyed\n";}
};

int main () {
myclass * pt;

pt = new myclass[3];
delete[] pt;

return 0;
}

Output:

myclass constructed
myclass constructed
myclass constructed
myclass destroyed
myclass destroyed
myclass destroyed

new & delete in C/C++

new :
void* operator new (std::size_t size) throw (std::bad_alloc);
void* operator new (std::size_t size, const std::nothrow_t& nothrow_constant) throw();
Allocate storage space

The first version allocates size bytes of storage space, aligned to represent an object of that size, and returns a non-null pointer to the first byte of this block. On failure, it throws a bad_alloc exception.

The second version is the nothrow version. It does the same as the first version, except that on failure it returns a null pointer instead of throwing an exception.

operator new are declared in the global namespace, not in the std namespace.
The first and second versions are implicitly declared in every translation unit of a C++ program: The header does not need to be included for them to be present.

operator new can be called explicitly as a regular function, but in C++, new is an operator with a very specific behavior: An expression with the new operator, first calls function operator new with the size of its type specifier as first argument, and if this is successful, it then automatically initializes or constructs the object (if needed). Finally, the expression evaluates as a pointer to the appropriate type.


delete :
void operator delete (void* ptr) throw ();
void operator delete (void* ptr, const std::nothrow_t& nothrow_constant) throw();
Deallocate storage space

The first and second versions deallocate the memory block pointed by ptr (if not-null), releasing the storage space previously allocated to it by a call to operator new and making that pointer location invalid.

The second and third versions cannot be implicitly called by the operator expression (the delete operator calls once the function operator delete for each of its arguments). Although they can be called explicitly as operator new function calls, their default definitions serve no particular purpose - they are provided as counterparts for the operator new functions and called accordingly when done automatically.

operator delete can be called explicitly as a regular function, but in C++, delete is an operator with a very specific behavior: An expression with the delete operator, first calls the appropriate destructor (if needed), and then calls function operator delete to release the storage.

// operator delete example
#include < iostream >
#include < new >
using namespace std;

struct myclass {
myclass() {cout <<"myclass constructed\n";} ~myclass() {cout <<"myclass destroyed\n";} }; int main () { myclass * pt; pt = new myclass; delete pt; return 0; } Output: myclass constructed myclass destroyed Example of a new: #include < iostream >
#include < new >
using namespace std;

struct myclass {myclass() {cout <<"myclass constructed\n";}};

int main () {

int * p1 = new int;
// same as:
// int * p1 = (int*) operator new (sizeof(int));

int * p2 = new (nothrow) int;
// same as:
// int * p2 = (int*) operator new (sizeof(int),nothrow);

myclass * p3 = (myclass*) operator new (sizeof(myclass));
// (!) not the same as:
// myclass * p3 = new myclass;
// (constructor not called by function call, even for non-POD types)

new (p3) myclass; // calls constructor
// same as:
// operator new (sizeof(myclass),p3)

return 0;
}

Output: myclass constructed

malloc,calloc,realloc and free

malloc(),calloc(),realloc() & free():

malloc (memory allocation) is used to dynamically allocate memory at run time. Possible uses for this function are:
Read records of an unknown length.
Read an unknown number of database records.
Link lists.
The simplest way to reserve memory is to code something like:

main()
{
char string[1000];

strcpy (string, "Some text");
}
The example above has two problems:

If the data is less than 1000 bytes we are wasting memory.
If the data is greater than 1000 bytes the program is going to crash.
The 1000 bytes are reserved throught out the life of the program. If this was a long running program that rarely used the memory, it would again be wasteful.
malloc allows us to allocate exactly the correct amount of memory and with the use of free only for the time it is required.

Library: stdlib.h

Prototype: void *malloc(size_t size);

Syntax: char * String;

String = (char *) malloc(1000);
Looking at the example syntax above, 1000 bytes are reserved and the pointer String points to the first byte. The 1000 bytes are NOT initialized by malloc. If the memory is NOT available, a NULL pointer is returned.

The calloc() Function
The standard C library declares the function calloc() in as follows:

void *calloc(size_t elements, size_t sz);
calloc() allocates space for an array of elements, each of which occupies sz bytes of storage. The space of each element is initialized to binary zeros. In other words, calloc() is similar to malloc(), except that it handles arrays of objects rather than a single chunk of storage and that it initializes the storage allocated. The following example allocates an array of 100 int's using calloc():


int * p = (int*) calloc (100, sizeof(int));
Remember that in C++, you have better alternatives to calloc() and malloc(), namely new and new [], and that these C functions should only be used for allocating POD (Plain Old Data) objects; never class objects. However, if you're using C or maintaining legacy C code, you might get across this function.

realloc:
void * realloc ( void * ptr, size_t size );
Reallocate memory block

The size of the memory block pointed to by the ptr parameter is changed to the size bytes, expanding or reducing the amount of memory available in the block.

The function may move the memory block to a new location, in which case the new location is returned. The content of the memory block is preserved up to the lesser of the new and old sizes, even if the block is moved. If the new size is larger, the value of the newly allocated portion is indeterminate.

In case that ptr is NULL, the function behaves exactly as malloc, assigning a new block of size bytes and returning a pointer to the beginning of it.

In case that the size is 0, the memory previously allocated in ptr is deallocated as if a call to free was made, and a NULL pointer is returned.

Return Value:A pointer to the reallocated memory block, which may be either the same as the ptr argument or a new location.
The type of this pointer is void*, which can be cast to the desired type of data pointer in order to be dereferenceable.
If the function failed to allocate the requested block of memory, a NULL pointer is returned.


/* realloc example: rememb-o-matic */
#include < stdio.h >
#include < stdlib.h >

int main ()
{
int input,n;
int count=0;
int * numbers = NULL;

do {
printf ("Enter an integer value (0 to end): ");
scanf ("%d", &input);
count++;
numbers = (int*) realloc (numbers, count * sizeof(int));
if (numbers==NULL)
{ puts ("Error (re)allocating memory"); exit (1); }
numbers[count-1]=input;
} while (input!=0);

printf ("Numbers entered: ");
for ( n=0; n < count; n++) printf ("%d ",numbers[n]); free (numbers); return 0; } The program prompts the user for numbers until a zero character is entered. Each time a new value is introduced the memory block pointed by numbers is increased by the size of an int. free:
Example
/* free example */
#include
#include

int main ()
{
int * buffer1, * buffer2, * buffer3;
buffer1 = (int*) malloc (100*sizeof(int));
buffer2 = (int*) calloc (100,sizeof(int));
buffer3 = (int*) realloc (buffer2,500*sizeof(int));
free (buffer1);
free (buffer3);
return 0;
}


This program has no output. Just demonstrates some ways to allocate and free dynamic memory using the cstdlib functions.

Also, check out Free ISTQB Training Material here

www.testing4success.com - Application QA/Testing     Mobile App QA/Testing     Web Testing     Training
Iphone App QA  Android App QA  Web QA 

Avoid Using malloc() and free() in C++

Avoid Using malloc() and free() in C++
The use of malloc() and free() functions in a C++ file is not recommended and is even dangerous:
1. malloc() requires the exact number of bytes as an argument whereas new calculates the size of the allocated object automatically. By using new, silly mistakes such as the following are avoided:


long * p = malloc(sizeof(short)); //p originally pointed to a short;
//changed later (but malloc's arg was not)
2. malloc() does not handle allocation failures, so you have to test the return value of malloc() on each and every call. This tedious and dangerous function imposes performance penalty and bloats your .exe files. On the other hand, new throws an exception of type std::bad_alloc when it fails, so your code may contain only one catch(std::bad_alloc) clause to handle such exceptions.

3. As opposed to new, malloc() does not invoke the object's constructor. It only allocates uninitialized memory. The use of objects allocated this way is undefined and should never occur. Similarly, free() does not invoke its object's destructor.

itoa & atoi - C/C++

itoa & atoi - C/C++

itoa:
char * itoa ( int value, char * str, int base );
Convert integer to string (non-standard function)

Converts an integer value to a null-terminated string using the specified base and stores the result in the array given by str parameter.

If base is 10 and value is negative, the resulting string is preceded with a minus sign (-). With any other base, value is always considered unsigned.

Return Value:A pointer to the resulting null-terminated string, same as parameter str.

This function is not defined in ANSI-C and is not part of C++, but is supported by some compilers.

A standard-compliant alternative for some cases may be sprintf:
sprintf(str,"%d",value) converts to decimal base.
sprintf(str,"%x",value) converts to hexadecimal base.
sprintf(str,"%o",value) converts to octal base.


/* itoa example */
#include < stdio.h >
#include < stdlib.h >

int main ()
{
int i;
char buffer [33];
printf ("Enter a number: ");
scanf ("%d",&i);
itoa (i,buffer,10);
printf ("decimal: %s\n",buffer);
itoa (i,buffer,16);
printf ("hexadecimal: %s\n",buffer);
itoa (i,buffer,2);
printf ("binary: %s\n",buffer);
return 0;
}

Output:
Enter a number: 1750
decimal: 1750
hexadecimal: 6d6
binary: 11011010110


atoi:

int atoi ( const char * str );
Convert string to integer

Parses the C string str interpreting its content as an integral number, which is returned as an int value.

The function first discards as many whitespace characters as necessary until the first non-whitespace character is found. Then, starting from this character, takes an optional initial plus or minus sign followed by as many numerical digits as possible, and interprets them as a numerical value.

The string can contain additional characters after those that form the integral number, which are ignored and have no effect on the behavior of this function.

If the first sequence of non-whitespace characters in str is not a valid integral number, or if no such sequence exists because either str is empty or it contains only whitespace characters, no conversion is performed.

Return Value-On success, the function returns the converted integral number as an int value.
If no valid conversion could be performed, a zero value is returned.

/* atoi example */
#include < stdio.h >
#include < stdlib.h >

int main ()
{
int i;
char szInput [256];
printf ("Enter a number: ");
fgets ( szInput, 256, stdin );
i = atoi (szInput);
printf ("The value entered is %d. The double is %d.\n",i,i*2);
return 0;
}

Output:

Enter a number: 73
The value entered is 73. The double is 146.


Also, check out Free ISTQB Training Material here

www.testing4success.com - Application QA/Testing     Mobile App QA/Testing     Web Testing     Training
Iphone App QA  Android App QA  Web QA 

Reverse a string C/C++

#include < iostream >
#include < string >

using namespace std;

void reverseStr(string& x)
{
string temp = "";

int len = x.length();

for(int i = len - 1; i >= 0; --i)
{
temp += x[i];
}

x = temp;
}

int main()
{
string x = "Hello World!";

cout << "x = " << x << endl;

reverseStr(x);

cout << "x = " << x << endl;

return 0;
}

Sunday, December 27, 2009

fseek C/C++

fseek

int fseek ( FILE * stream, long int offset, int origin );

header:

Sets the position indicator associated with the stream to a new position defined by adding offset to a reference position specified by origin.
The End-of-File internal indicator of the stream is cleared after a call to this function, and all effects from previous calls to ungetc are dropped.
When using fseek on text files with offset values other than zero or values retrieved with ftell, bear in mind that on some platforms some format transformations occur with text files which can lead to unexpected repositioning.
On streams open for update (read+write), a call to fseek allows to switch between reading and writing.

stream:Pointer to a FILE object that identifies the stream.
offset:Number of bytes to offset from origin.
origin:Position from where offset is added. It is specified by one of the following constants defined in :
SEEK_SET Beginning of file
SEEK_CUR Current position of the file pointer
SEEK_END End of file

Return Value:
If successful, the function returns a zero value.
Otherwise, it returns nonzero value.

/* fseek example */
#include

int main ()
{
FILE * pFile;
pFile = fopen ( "example.txt" , "w" );
fputs ( "This is an apple." , pFile );
fseek ( pFile , 9 , SEEK_SET );
fputs ( " sam" , pFile );
fclose ( pFile );
return 0;
}


After this code is successfully executed, the file example.txt contains:
This is a sample.