Useful macros, functions and tricks

Submitted by:David Villa

Date added:23 March, 2013


C code example for useful macros, functions and tricks

Tags: function , macros

Code Snippet:

Useful macros, functions and tricks for noobz. We've all been there;
the following are really useful when learning (and later on).


#include <stdio.h> //as always; for any I/O
#include <string.h> //for strlen function
#include <stdlib.h> //for malloc & exit
#include <locale.h> //for setlocale


/* string length for malloc */
#define MALLEN(x) (strlen(x) + 1)
+1 needed for the string closing byte '\0'
usage: string = malloc(MALLEN(line));

/* check if memory allocation failed */
#define MALCHK(x) if(!x){puts("Out of memory"); exit(EXIT_FAILURE);}
sometimes malloc/calloc/realloc fails (eg. not enough free memory)
usage: MALCHK(string);

/* check if a file was opened properly */
#define FILCHK(x) if(!x){printf("Cannot open file %s\n", x); exit(EXIT_FAILURE);}
it alerts when eg. the file doesn't exist
usage: FILCHK(fp);


/* a dynamic string */
char static_string[] = "herp derp";
char *dynamic_string;
dynamic_string = malloc(MALLEN(static_string)); //allocate memory
strcpy(dynamic_string, static_string); //dynamic_string is now "herp derp"
the copying can also be done with sprintf:
sprintf(dynamic_string, "%s", static_string);

/* a dynamic array of numbers (of any type) */
int i;
int static_intarr[] = {0, 1, 2, 3};
int *dynamic_intarr;
for(i = 0; i < 4; ++i)
dynamic_intarr = realloc(dynamic_intarr, (i + 1) * sizeof(int));
//dynamic_intarr has now enough memory for i + 1 int elements
MALCHK(dynamic_intarr); //check memory allocation
dynamic_intarr[i] = static_intarr[i]; //copy the integer
for every i realloc assigns more memory to the array
it could be done once before the loop if the number of elements (n) is known:
dynamic_intarr = malloc(n * sizeof(int));
malloc is for initial memory allocation, realloc for REallocations

/* a dynamic string array */
int i;
char static_stringarr[4][5] = {"hurr", "durr", "herp", "derp"};
char **dynamic_stringarr;
for(i = 0; i < 4; ++i)
dynamic_stringarr = realloc(dynamic_stringarr, (i + 1) * sizeof(*dynamic_stringarr));
//dynamic_stringarr has now enough memory for i + 1 string _spots_
dynamic_stringarr[i] = malloc(LEN(static_stringarr[i]));
//dynamic_stringarr[i] has now enough memory for the static_stringarr[i] string
strcpy(dynamic_stringarr[i], static_stringarr[i]);
//dynamic_stringarr[i] is now the same as static_stringarr[i]
instead of multiple reallocs, one malloc above the loop is sufficient
provided that the number of strings (n) to insert in the dynamic array is known:
dynamic_stringarr = malloc(n * sizeof(*dynamic_stringarr));

/* variable swapping funtion */
void swap(type *x, type *y)
type z; //the same type as chosen in the brackets above

z = *x;
*x = *y;
*y = z;
it is very useful in arrays (sorting, etc.)
usage: swap(&x, &y); in arrays: swap(&array[k - 1], &array[k]);

/* convert any variable to a string */
char string[n] //any string long enough for the variable, eg. string[5]
sprintf(string, "%T", var);
where string - output string, %T - conversion specifier, eg. %lf, var - variable
usage: same as with printf; %d for ints, %f for floats etc., eg.:
sprintf(string, "%d", someint);
can be combined with other things:
sprintf(string, "%d-%f\t%s\n", someint, somefloat, string);

/* clear, easy string concatenation */
sprintf(bigstring, "%s%s", string1, string2);
can be used for any combination of strings, chars and other

/* set all locale to your native one */
setlocale(LC_ALL, "");
usage: at the beginning of the code (eg. once at the top of main)
particularly useful with the decimal mark (in eg. EU it's a comma, not a dot)

/* rewind the processed file */
allows file processing back from its beginning
useful with file analysis prior to actual processing
or multiple passing of the file