C

Simple C Math Program

Blog tags: 

While writing an exercise for my book currently in editing, I wrote a quick utility for math operations on the CLI in Bash

/**
 * @file main.c
 * @author Ron Brash
 * @date Nov 16, 2017
 * @brief Create a simple math helper for CLI usage in Bash
 *
 * @note To compile:
 *      gcc -Wall -O2 -o mhelper main.c -lm
 */
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>

#include <math.h>

#define USAGE "%s <param1> <operation> <param2>\n"
#define TRUE 1
#define FALSE 0

// Function pointer for math operations
typedef void (*mathfpr_t) (double, double, uint8_t, uint8_t);

// Typedef of structure containing math operation function pointers
// think array of callbacks
typedef struct mathop_s {
        char op;
        mathfpr_t func;
} mathop_t;

// Forward function declarations
static void subtract(double a, double b, uint8_t a_type, uint8_t b_type);
static void addition(double a, double b, uint8_t a_type, uint8_t b_type);
static void divide(double a, double b, uint8_t a_type, uint8_t b_type);
static void multiply(double a, double b, uint8_t a_type, uint8_t b_type);
static inline int is_whole(double a);
static inline int has_decimal(char *a);

// Declared function pointer array
static mathop_t math_arr[] = { {'-', subtract}, {'+', addition}, {'*', multiply}, {'/', divide}, };

static inline int has_decimal(char *a)
{

        int len = 0;
        for (len = strlen(a); len > 0; len--) {
                if (a[len] == '.') {
                        return (TRUE);
                }
        }
        return (FALSE);
}

static inline int is_whole(double a)
{
        if (a == (int)a) {
                // true
                return (TRUE);
        }
        // false
        return (FALSE);
}

static inline void print_val(double a, int type)
{

        if (type == 0) {
                printf("%.2f\n", a);    // Only print out two decimal points
        } else {
                printf("%i\n", (int)a);
        }
}

static void subtract(double a, double b, uint8_t a_type, uint8_t b_type)
{

        double res = a - b;
        print_val(res, is_whole(res));
}

static void divide(double a, double b, uint8_t a_type, uint8_t b_type)
{

        double res = a / b;
        print_val(res, is_whole(res));
}

static void multiply(double a, double b, uint8_t a_type, uint8_t b_type)
{

        double res = a * b;
        print_val(res, is_whole(res));
}

static void addition(double a, double b, uint8_t a_type, uint8_t b_type)
{

        double res = a + b;
        print_val(res, is_whole(res));
}

static void set_param(char *param, double *val, int *type)
{

        char *tmp;
        if (has_decimal(param) > 0) {
                *val = strtof(param, NULL);
                *type = 1;
        } else {
                *val = strtoll(param, &tmp, 10);
        }

}

int main(int argc, char *argv[])
{

        /// Initialize function variables in the stack
        double a = 0, b = 0;
        int a_type = 0, b_type = 0;
        char op = '\0';

        /// There are four parameters including the binary itself on the CLI
        if (argc == 4) {

                /// Copy params to values
                strncpy(&op, argv[2], sizeof(char));

                /// Let's set &  check if it has a decimal (signify a float early)
                set_param(argv[1], &a, &a_type);
                set_param(argv[3], &b, &b_type);

                int i = 0;
                for (i = 0; i < sizeof(math_arr); i++) {
                        if (op == math_arr[i].op) {
                                math_arr[i].func(a, b, a_type, b_type);
                                return (TRUE);
                                break;
                        }
                }

        }

        printf(USAGE, argv[0]);
        return (FALSE);
}

Enjoy

Simple C Function Pointer Example

Blog tags: 

Here is a simple function pointer example I wrote for one of my friends just learning to program in C - it should be easy to follow:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

typedef void (*ledFuncPtr) (int[], int);

void myFunctionTest(int pins[], int size)
{

        int i = 0;
        for (i = 0; i <= size; i++) {
                printf("val: %d\n", pins[i]);
        }
}

Simple C fread and fseek to bulk read lines separated with a \n

Blog tags: 

Here is simple file chunker that writes only complete complete records read in from a file to another file. For example, there are JSON records delimited with a '\' character and because they are variable in size, the buffer size WILL not align and therefore needs us to read X bytes, then walk backwards until we find the last complete record.

This requires us to use fseek (fseek(fp,i-tmp_bytes_read,SEEK_CUR);) to re-adjust the filepointer such that the next read will begin at the correct point.

Simple cross array of sizes

Blog tags: 

I recently coded this in less than 30 seconds for a student showing how you can create a simple 2D array to return sizes of structs to be used inside of buffer array function. This should be explanatory by itself... the use - its up to you.

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

typedef struct type1_s {
    int data;
}type1_t;

typedef struct type2_s {
    int data;
    int data2;
}type2_t;

Pages

Subscribe to RSS - C