Random C snippets

Last edit

Added:

> == Getting specific bytes from a word ==
> If you have a longer (like say, 64-bits) word and you need a specific byte from that word, use a combination of right-shifting and masking. Or perhaps you only need the first three bytes of a 64-bits word, and you can just right-shift:
> int i=0xAABBCCDD;
> i = (i >> 8);
> /* i is now 0xAABBCC */
>
> int j=0xAABBCCDD;
> j = (j >> 24);
> /* j is now 0xAA */


Completely read a file

To completely read a file into a string, see below. Warning: uses glibc-specific getline() function.

    #define _GNU_SOURCE
    #include <stdio.h>
    char* line = NULL;
    char* str = NULL;
    FILE* err_file;
    size_t sz = 0;
    err_file = fopen(err_filename, "r");
    if(err_file == NULL) {
        print_err(ID,"Error opening file %s\n",err);
        exit(errno);
    }
    while(getline(&line, &sz, err_file) != -1) {
        if(str == NULL) {
            /* first run of this loop */
            str = (char*)malloc(strlen(line) + 1);
            strcpy(str, line);
        } else {
            char* tmp = (char*)realloc(str, strlen(str) + strlen(line) + 1);
            if(!tmp) {
                perror("Couldn't add last read line to buffer");
                exit(EXIT_FAILURE);
            }
            str = tmp;
            strcpy(str + strlen(str), line);
        }
    }
    fclose(err_file);
    free(line);

Using the syslog facility

  #include <syslog.h>
  int main(void)
  {
      openlog("TheTestSyslogProject", 0, LOG_USER);
      syslog(LOG_INFO, "Test Message from outer space");
      return 0;
  }

Bitwise operators

Reminders:

See also Bitwise operation.

Flipping

To flip a bit, use XOR:

  int main(void) {
    int i = 0xF;    /* In binary, 1111 */
    printf("0x%x\n", i^0x8);  /* In binary, 1000 */
    return 0;
  }

This will yield:

  0x7

Which is in binary 0111.

Masking

To get the first four bits, AND with zero:

  int i = 0xFFFF;
  i = i & 0x0004;  /* Set all bits to zero except the first four */

Setting a bit

To make a value with one bit set, just shift 1 to the left. We'll name the right-most bit bit 0 (but see below).

  int i = (1 << 0);   /* Set right-most bit to 1, decimal value 1 */
  int j = (1 << 1);   /* Set bit 1 to 1, decimal value 2 */
  int k = (1 << 2);   /* Set bit 2 to 1, decimal value 4 */
  int l = (1 << 3);   /* Set bit 3 to 1, decimal value 8 */
  int m = (1 << 4);   /* Set bit 4 to 1, decimal value 16 */
  /* et cetera */

Getting specific bytes from a word

If you have a longer (like say, 64-bits) word and you need a specific byte from that word, use a combination of right-shifting and masking. Or perhaps you only need the first three bytes of a 64-bits word, and you can just right-shift:

  int i=0xAABBCCDD;
  i = (i >> 8);
  /* i is now 0xAABBCC */
  
  int j=0xAABBCCDD;
  j = (j >> 24);
  /* j is now 0xAA */

Automatic string allocation

Use the asprintf() function to automatically allocate memory for your strings. Note that this is very useful but not portable outside GNU's libc. Example:

  #define _GNU_SOURCE
  #include <stdio.h>
  ...
  ...
  char* mystring;
  asprintf(&mystring, "Hello world, here's a string: %d\n", "yawn");

Using this function avoids the problem where you generate segmentation faults because you forgot to allocate memory, or just didn't allocate enough.