Sunday, December 27, 2009

How to read arguments in shell program

How to read arguments in shell program

#!/bin/sh
for i in $*
do
echo $i
done

$# returns the number of parameters that are passed to a shell script
$? returns the exit code of the last executed command (0 : Successful, 1 or other: Failed)




On executig the above script with any number of command-line arguments it will display all the parameters.

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.

fopen

fopen

FILE * fopen ( const char * filename, const char * mode );

Opens the file whose name is specified in the parameter filename and associates it with a stream that can be identified in future operations by the FILE object whose pointer is returned. The operations that are allowed on the stream and how these are performed are defined by the mode parameter.

filename
C string containing the name of the file to be opened. This paramenter must follow the file name specifications of the running environment and can include a path if the system supports it.

mode
C string containing a file access modes. It can be:
"r" Open a file for reading. The file must exist.
"w" Create an empty file for writing. If a file with the same name already exists its content is erased and the file is treated as a new empty file.
"a" Append to a file. Writing operations append data at the end of the file. The file is created if it does not exist.
"r+" Open a file for update both reading and writing. The file must exist.
"w+" Create an empty file for both reading and writing. If a file with the same name already exists its content is erased and the file is treated as a new empty file.
"a+" Open a file for reading and appending. All writing operations are performed at the end of the file, protecting the previous content to be overwritten. You can reposition (fseek, rewind) the internal pointer to anywhere in the file for reading, but writing operations will move it back to the end of file. The file is created if it does not exist.

With the mode specifiers above the file is open as a text file. In order to open a file as a binary file, a "b" character has to be included in the mode string. This additional "b" character can either be appended at the end of the string (thus making the following compound modes: "rb", "wb", "ab", "r+b", "w+b", "a+b") or be inserted between the letter and the "+" sign for the mixed modes ("rb+", "wb+", "ab+").
Additional characters may follow the sequence, although they should have no effect. For example, "t" is sometimes appended to make explicit the file is a text file.
In the case of text files, depending on the environment where the application runs, some special character conversion may occur in input/output operations to adapt them to a system-specific text file format. In many environments, such as most UNIX-based systems, it makes no difference to open a file as a text file or a binary file; Both are treated exactly the same way, but differentiation is recommended for a better portability.

Return Value

If the file has been succesfully opened the function will return a pointer to a FILE object that is used to identify the stream on all further operations involving it. Otherwise, a null pointer is returned.

/* fopen example */
#include
int main ()
{
FILE * pFile;
pFile = fopen ("myfile.txt","w");
if (pFile!=NULL)
{
fputs ("fopen example",pFile); //this is same as puts(str);
//fputs() - Writes the string to a file as we can see from
//mode as "w"
fclose (pFile);
}
return 0;
}


/* fopen example */
#include
int main ()
{
FILE * pFile;
pFile = fopen ("myfile.txt","r");
if (pFile!=NULL)
{
fgets ("fopen example",pFile); //this is same as puts(str);
//fgets() - Reads the string from a file as we can see from
//mode as "r"
fclose (pFile);
}
return 0;
}

size_t in C/C++

size_t

size_t corresponds to the integral data type returned by the language operator sizeof and is defined in the header file (among others) as an unsigned integral type.

This is an unsigned integer type used to represent the sizes of objects. The result of the sizeof operator is of this type, and functions such as malloc and memcpy accept arguments of this type to specify object sizes.

It is also used as the return type for strcspn, strlen, strspn and strxfrm to return sizes and lengths.

Here is a sample problem, which will help us understand it better:
for (int i=0;i < strlen(pathcmd);i++){//this line cause a warning

warning C4018: '<' : signed/unsigned mismatch

strlen returns a number of type 'size_t'. size_t is an unsigned type and
you are comparing it to an int, a signed type.

Two solutions to remove the warning:

1. Change the type of the variable 'i' to 'size_t'.
2. staic_cast i to "unsigned" type.

Which way is better in C++?

Change 'i' to type 'size_t'.

Or better yet, replace your char array 'pathcmd'
with a 'std::string' object, and write:

std::string pathcmd("whatever");
for(std::string::size_type i = 0; i < pathcmd.size(); ++i)
/***end of example*****/


Careful--->
assigning size_t type variable to int works fine.
Only if the value in the size_t variable can be represented by int. Otherwise you've invoked undefined behavior. The only way this assignment could be safe is if size_t is smaller than int, which isn't a common case.


in printf size_t has format specifier as %z ( courtesy Amitesh Singh, thanks :)

Thursday, December 24, 2009

Funny "C"- Weird Pointers

You have a declaration:

int* ptr_a, ptr_b;

Given this, what is the type of ptr_b? int *, right?

Wrong!

C’s declaration syntax ignores the pointer asterisks when carrying a type over to multiple declarations. If you split the declaration of ptr_a and ptr_b into multiple statements, you get this:

int *ptr_a;
int ptr_b;

It’s possible to do the single-line declaration in a clear way. This is the immediate improvement:

int *ptr_a, ptr_b;

Notice that the asterisk has moved. It is now right next to the word ptr_a. A subtle implication of association.

Finally, I should point out that you can do this just fine:

int *ptr_a, *ptr_b;

Call by Value and Call by Reference

The arguments passed to function can be of two types namely

1. Values passed
2. Address passed

The first type refers to call by value and the second type refers to call by reference.

For instance consider program1

main()
{
int x=50, y=70;
interchange(x,y);
printf(“x=%d y=%d”,x,y);
}

interchange(x1,y1)
int x1,y1;
{
int z1;
z1=x1;
x1=y1;
y1=z1;
printf(“x1=%d y1=%d”,x1,y1);
}

Here the value to function interchange is passed by value.

Consider program2

main()
{
int x=50, y=70;
interchange(&x,&y);
printf(“x=%d y=%d”,x,y);
}

interchange(x1,y1)
int *x1,*y1;
{
int z1;
z1=*x1;
*x1=*y1;
*y1=z1;
printf(“*x=%d *y=%d”,x1,y1);
}

Here the function is called by reference. In other words address is passed by using symbol & and the value is accessed by using symbol *.

The main difference between them can be seen by analyzing the output of program1 and program2.

The output of program1 that is call by value is

x1=70 y1=50
x=50 y=70

But the output of program2 that is call by reference is

*x=70 *y=50
x=70 y=50

This is because in case of call by value the value is passed to function named as interchange and there the value got interchanged and got printed as

x1=70 y1=50

and again since no values are returned back and therefore original values of x and y as in main function namely

x=50 y=70 got printed.

But in case of call by reference address of the variable got passed and therefore what ever changes that happened in function interchange got reflected in the address location and therefore the got reflected in original function call in main also without explicit return value. So value got printed as
*x=70 *y=50 and x=70 y=50

Call By Value/Call By Reference is not new to C++. It has been around for a while. In C, we call/pass by value by passing variables, and we call/pass by reference by passing either pointers, or addresses of variables. See example below.
Eg:
main()
{
int myInt, *pMyIntPtr;
myInt = 10;
pMyIntPtr = &myInt; // assigning address of myInt to pMyIntPtr

MyCbyVal (myInt); // Call by value, or pass by value
MyCbyRef (pMyIntPtr); // Call/pass by reference (passing a pointer)
MyCbyRef (&myInt); // Call/pass by reference (passing address of myInt)
return myInt;
}

Any changes made to the parameter by the MyCbyVal function cannot be seen in the main function above. However, any changes made to the parameters of MyCbyRef (both statements) will be reflected in MyInt of main function, after the statements are executed.

P.S. In call by value the values may change in the calling function but those are not reflected in the main function but in the call by reference the calling function causes a change in the value of the arguments passed in the main function.

Wednesday, December 23, 2009

printf C++

Here's a quick summary of the available print format specifiers:

%c character
%d decimal (integer) number (base 10)
%e exponential floating-point number
%f floating-point number
%i integer (base 10)
%o octal number (base 8)
%s a string of characters
%u unsigned decimal (integer) number
%x number in hexadecimal (base 16)
%% print a percent sign
\% print a percent sign
%p print the pointer address

Controlling printf integer width
The "%3d" specifier means a minimum width of three spaces, which, by default, will be right-justified. (Note: the alignment is not currently being displayed properly here.)

printf("%3d", 0); 0
printf("%3d", 123456789); 123456789
printf("%3d", -10); -10
printf("%3d", -123456789); -123456789

Left-justifying printf integer output
To left-justify those previous printf examples, just add a minus sign (-) after the % symbol, like this:

printf("%-3d", 0); 0
printf("%-3d", 123456789); 123456789
printf("%-3d", -10); -10
printf("%-3d", -123456789); -123456789

The printf zero-fill option
To zero-fill your integer output, just add a zero (0) after the % symbol, like this:

printf("%03d", 0); 000
printf("%03d", 1); 001
printf("%03d", 123456789); 123456789
printf("%03d", -10); -10
printf("%03d", -123456789); -123456789

printf - integers with formatting
Here is a collection of examples for integer printing. Several different options are shown, including a minimum width specification, left-justified, zero-filled, and also a plus sign for positive numbers.

Description Code Result
At least five wide printf("'%5d'", 10); ' 10'
At least five-wide, left-justified printf("'%-5d'", 10); '10 '
At least five-wide, zero-filled printf("'%05d'", 10); '00010'
At least five-wide, with a plus sign printf("'%+5d'", 10); ' +10'
Five-wide, plus sign, left-justified printf("'%-+5d'", 10); '+10 '

printf - floating point numbers
Here are several examples showing how to print floating-point numbers.

Description Code Result
Print one position after the decimal printf("'%.1f'", 10.3456); '10.3'
Two positions after the decimal printf("'%.2f'", 10.3456); '10.35'

Eight-wide, two positions after the decimal
printf("'%8.2f'", 10.3456); ' 10.35'

Eight-wide, four positions after the decimal
printf("'%8.4f'", 10.3456); ' 10.3456'

Eight-wide, two positions after the decimal, zero-filled
printf("'%08.2f'", 10.3456); '00010.35'

Eight-wide, two positions after the decimal, left-justified
printf("'%-8.2f'", 10.3456); '10.35 '
Printing a much larger number with that same format
printf("'%-8.2f'", 101234567.3456); '101234567.35'

How to print strings with printf formatting
Here are several printf formatting examples that show how to format string output with printf format specifiers.

Description Code Result
A simple string printf("'%s'", "Hello"); 'Hello'
A string with a minimum length printf("'%10s'", "Hello"); ' Hello'
Minimum length, left-justified printf("'%-10s'", "Hello"); 'Hello '