[1] Case-insensitive String Comparison
strcasecmp()
is the case-insensitive version of strcmp()
. When building, make sure to include strings.h
(note the plural form).
strncasecmp()
is the counterpart to strncmp()
.
.. #include <string.h> void main(int argc, char** argv) .. printf("\n\"%s\" and \"%s\" are ", argv[1], argv[2]); strcasecmp(argv[1], argv[2]) ? printf(" .. not identical") : printf(" .. identical"); .. % ./strcompare next NeXT "next" and "NeXT" are .. identical
[2] Initializing a Variable Length Array
As of the length of the variable length array is not known to the compiler at compile time, initializing a variable length automatic array with some default value usually results in a compilation error.
eg.,% cat -n varlen.c 1 #include <stdlib.h> 2 3 void main(int argc, char** argv) { 4 int size=atoi(argv[1]); 5 int array[size] = { 0 }; 6 } /home/gmandali/C % cc -o varlen varlen.c "varlen.c", line 5: variable length array can not be initialized: array cc: acomp failed for varlen.c
One option is to explicitly initialize each element in the array to the desired default value.
eg.,% cat -n varlen.c 1 #include <stdlib.h> 2 3 void main(int argc, char** argv) { 4 int size=atoi(argv[1]); 5 int array[size]; 6 for (int i = 0; i < size; ++i) 7 array[i] = 0; 8 } % cc -o varlen varlen.c %
Another option is to rely on memset()
.
% cat -n varlen.c 1 #include <stdlib.h> 2 #include <string.h> 3 4 void main(int argc, char** argv) { 5 int size=atoi(argv[1]); 6 int array[size]; 7 memset(array, 0, sizeof(array)); 8 } % cc -o varlen varlen.c %
In this case, sizeof
operator evaluates the operand (variable length array).
[3] Check if a Process is Alive
kill()
function can be used to send a null signal (signal 0) to check the validity of a process.
% cat -n chkproc.c 1 #include <sys/types.h> 2 #include <signal.h> 3 #include <stdlib.h> 4 #include <stdio.h> 5 6 void main(int argc, char **argv) { 7 pid_t pid = atoi( argv[1] ); 8 int rc = kill( pid, 0 ); 9 if ( !rc ) { 10 printf("process with pid ( %d ) is alive", pid); 11 } else { 12 printf("process with pid ( %d ) is not found", pid); 13 } 14 } % cc -o chkproc chkproc.c % ps PID TTY TIME CMD 19846 pts/25 0:00 ps 28978 pts/25 0:00 bash % ./chkproc 28978 process with pid ( 28978 ) is alive % ./chkproc 28979 process with pid ( 28979 ) is not found
pid_t
is actually int
data type.
[4] Evaluating "( integer )
" Expression
This is a simple one but probably an important one to remember. When dealing with an expression that yields an integer or when testing an integer, only a value of zero evaluates to false. Everything else including negative numbers, floating point numbers, characters, strings, .. are evaluated to true. In other words, anything non-zero is true.
eg.,% cat -n ifexpr.c 1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <ctype.h> 4 5 void main(int argc, char **argv) { 6 printf("\n[ %10d ] : %s", 0, (0) ? "true" : "false" ); 7 printf("\n[ %10d ] : %s", 1, (1) ? "true" : "false" ); 8 printf("\n[ %10d ] : %s", -2, (-2) ? "true" : "false" ); 9 printf("\n[ %10s ] : %s", "dummy", ("dummy") ? "true" : "false" ); 10 printf("\n[ %10c ] : %s", 'C', ('C') ? "true" : "false" ); 11 printf("\n[ %10f ] : %s", 2.34, (2.34) ? "true" : "false" ); 12 printf("\n[ %10f ] : %s\n", 0.0000, (0.0000) ? "true" : "false" ); 13 } % cc -o ifexpr ifexpr.c % ./ifexpr [ 0 ] : false [ 1 ] : true [ -2 ] : true [ dummy ] : true [ C ] : true [ 2.340000 ] : true [ 0.000000 ] : false
[5] Variable Declaration in a switch { case: }
Statement
Let's start with an example that shows compilation failure.
% cat -n varincase.c 1 #include2 3 void main() { 4 switch ( 1 ) { 5 case 2: 6 int i = 15; 7 break; 8 default: 9 printf("default\n"); 10 } 11 } % cc -o varincase varincase.c "varincase.c", line 6: syntax error before or at: int "varincase.c", line 7: undefined symbol: i cc: acomp failed for varincase.c
In this example, identifier i
is being declared and initialized in the case
label of switch
statement. Since no linkage or no static
scope was specified,
identifier i
will have automatic storage duration that is local to the block containing the invocation (switch() { .. }
, that is).
However the problem with this code is that case <expression>
and default
are labels and the controlling expression in switch
statement causes the control to jump to
appropriate label. In the example, when the control is transferred to default
label, it enters the scope of identifier i
without initializing it [as it bypasses the case
where the identifier is being declared and initialized], which is not permitted. Therefore the fix is to declare the identifier (if at all needed) in its own compound statement so the scope is limited to that
compound statement. (A compond statement is a block of code.)
Adding curly braces around case 2:
statements will make the code compile and run as shown below.
% cat -n varincase.c 1 #include <stdio.h> 2 3 void main() { 4 switch ( 1 ) { 5 case 2: 6 { 7 int i = 15; 8 break; 9 } 10 default: 11 printf("default\n"); 12 } 13 } % cc -o varincase varincase.c % ./varincase default
(Stacked Paper CSS Theme Credit: Chris McLeod)