C vs Python

I saw this picture on Instagram on page of some guy that teaches python

I assume that what this guy meant is that python fits best for some kind of applications than c, and for some kind of applications c fits better than python, and not that c generally sucks compared to python.

Linked List

Linked list, is a dynamic data structure in c to store data. This post is cheat sheet to myself, for every time I need to build a linked list. This is not necessary the correct way of creating the linked list, but this is my way.

Main file.

/*
 ============================================================================
 Name        : LinkedList.c
 Author      : Tim Goldshmit
 Version     :
 Copyright   : Your copyright notice
 Description : Hello World in C, Ansi-style
 ============================================================================
 */

#include <stdio.h>
#include <stdlib.h>
#include "mylinkedlist.h"

int main(void)
{
	puts("!!!Kick this into gear!!!");
	struct my_list temp;
	memcpy(temp.mydata.full_name,"tim g",sizeof(temp.mydata.full_name));
	temp.mydata.id=1000;

	// create the root or the first node
	struct my_list root;
	memset (&root,0,sizeof(struct my_list));

	int i;
	for (i=1;i<10;i++)
	{
		temp.mydata.id=i;
		add_to_list(&root,&temp);
	}

	struct my_list *p;
	p=&root;

	remove_n_from_list(p,5);

	free_all(&root);

	return EXIT_SUCCESS;
}

the .h file

/*
 * mylinkedlist.h
 *
 *  Created on: Oct 6, 2019
 *      Author: timg
 */

#ifndef MYLINKEDLIST_H_
#define MYLINKEDLIST_H_

struct my_data
{
	char full_name[50];
	int id;
};

struct my_list
{
//	struct my_list *head;
	struct my_list *prev_node;
	struct my_list *next_node;
	struct my_data mydata;
};

int add_to_list(struct my_list *current_list,struct my_list *new_entry);
int free_all(struct my_list *any_entry);
int remove_n_from_list(struct my_list *entry_to_remove,int n);
#endif /* MYLINKEDLIST_H_ */

The .c file

/*
 * mylinkedlist.c
 *
 *  Created on: Oct 6, 2019
 *      Author: timg
 */

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

/**
 * Add to the end if the list
 * current_list - any member of the list
 * new_entry - data to enter. the pointers do not matter, it only copies the data
 */
int add_to_list(struct my_list *current_list,struct my_list *new_entry)
{
	//In case not at the end of the node. Move to the last node
	while (!current_list->next_node==NULL)
	{
		current_list=current_list->next_node;
	}

	struct my_list *new_node=(struct my_list*)malloc(sizeof(struct my_list));
	memset (new_node,0,sizeof(struct my_list));
	current_list->next_node=new_node;
	new_node->prev_node=current_list;
	memcpy(&new_node->mydata,&new_entry->mydata,sizeof(struct my_data));
	return 0;
}

/**
 *  Remove node number n from the list.
 *  To remove current node, in the list send address of the
 * node to the function with n=0
 */
int remove_n_from_list(struct my_list *entry_to_remove,int n)
{
	int i;
	for (i=0;i<n;i++)
	{
		if (entry_to_remove==NULL)
			return -1;
		entry_to_remove=entry_to_remove->next_node;
	}

	if (entry_to_remove->prev_node==NULL && entry_to_remove->next_node!=NULL)
		entry_to_remove->next_node->prev_node=NULL;
	else if (entry_to_remove->next_node==NULL && entry_to_remove->prev_node!=NULL)
		entry_to_remove->prev_node->next_node=NULL;
	else if (entry_to_remove->next_node!=NULL && entry_to_remove->prev_node!=NULL)
	{
		entry_to_remove->prev_node->next_node=entry_to_remove->next_node;
		entry_to_remove->next_node->prev_node=entry_to_remove->prev_node;
	}

	free (entry_to_remove);
	return 0;
}

/**
 * Frees all of the memory of the linked list
 */
int free_all(struct my_list *any_entry)
{
	// get to the first node
	while (!any_entry->prev_node==NULL)
		any_entry=any_entry->prev_node;

	// free nodes one by one
	struct my_list *temp;
	while (!any_entry==NULL)
	{
		temp=any_entry->next_node;
		free(any_entry);
		any_entry=temp;
	}


	return 0;
}

This also stored in github.

https://github.com/timgold81/LinkedList

Pinging host for a lot of time

TL;DR: use this program to track if a host up or down using ping.

Sometimes for some kind of a check, I need to ping a host for a lot of time and see when the ping wasn’t successful. The familiar ping program doesn’t fit that purpose. Ping’s lines will scroll back, and if at some point ping will be unsuccessful, there is no way to know when it happened.

I searched google for a program that will log pings and tell when they were successful and when they were not. Found some for free and some programs that costs money.

I created a simple python script that will do just that. In addition I compiled the script to executable file for windows.

The program will ping destination and print the time when the ping was successful or not. After that it will print every time the destination changes it’s status. Output example:

./pinger.py -s 10.0.2.31
Tracking 10.0.2.31:
system 10.0.2.31 up at 2018-04-02 10:37:05.976400
system 10.0.2.31 down at 2018-04-02 10:37:19.039902
system 10.0.2.31 up at 2018-04-02 10:37:26.063647

The program source code and executable file can be downloaded from my github page.

https://github.com/timgold81/pingtrack

Few c tips

TL;DR:

Use % instead of ‘if’ to reset counters
Use constants
Nest struct to keep your variables in one place

Here are a few tips to programmers in c out there. I don’t say that this is the correct way to program in c. It just a few tricks that I do when programming.
Anyway, let’s say you have a function that tracking some information in an array, in length of 10.
I have the following code for this:

#include <stdio.h>
#include <string.h>
 
struct history
{
    int value;
}my_history[10];
int history_pointer=0;
 
int history_handler(int value_to_add)
{
    my_history[history_pointer].value=value_to_add;
    history_pointer++;
    if (history_pointer==10) history_pointer=0;
}
 
int main (int argc, char *argv[])
{
    int i;
    memset(&my_history,0,sizeof(my_history));
    for (i=0;i<100;i++)
        history_handler(i);
     for (i=0;i<10;i++)
        printf ("%d - %d\n",i,my_history[i]);
    return 0;    
}

For this code I”ll change a few things:

  1. I”ll remove the if in the function handler – prettier and faster code
  2. I”ll change the length of the array to constant – will allow easily to change the size of the array in the future
  3. And I”ll nest the array with a pointer – will give me one array belonging to my function, so anyone else reading my program will understand it better, and it keeps all my variable in one place. 

End result will be:

#include <stdio.h>
#include <string.h>
#define HISTORY_LENGTH 10
struct history_data
{
    int value;
};
struct history
{
    struct history_data my_data[HISTORY_LENGTH];
    int history_pointer;
}my_history;
int history_handler(int value_to_add)
{
    my_history.my_data[my_history.history_pointer].value=value_to_add;
    my_history.history_pointer=(my_history.history_pointer+1)%HISTORY_LENGTH;
}
 
int main (int argc, char *argv[])
{
    int i;
    printf("main-imp\n");
    memset(&my_history,0,sizeof(my_history));
    for (i=0;i<100;i++)
        history_handler(i);
     for (i=0;i<10;i++)
        printf ("%d - %d\n",i,my_history.my_data[i]);
    return 0;    
}

The first change I’ve added the constant instead of 10 :

#define HISTORY_LENGTH 10

I later changed every instance of 10 with the constant HISTORY_LENGTH. If in the future I will need to change the history length I will only change it here.

In the second changed, instead of using the history pointer as a global variable, I nested one struct within another. This keeps all my variable in one “place” under one struct, and any future change will be done there.

struct history_data
{
    int value;
};
 
struct history
{
    struct history_data my_data[HISTORY_LENGTH];
    int history_pointer;
}my_history;

In the third change, I removed the if:

if (history_pointer==10) history_pointer=0;

And then I changed the increment the pointer from

history_pointer++;

To

my_history.history_pointer=(my_history.history_pointer+1)%HISTORY_LENGTH;

This means increment the history pointer by 1, and use the ‘%’ remainder operand. This do the same as when this was an ‘if’ statement, but this is faster and better looking.

Why do I use vim?

TL;DR: shortcuts. 99.9% of code editors has vim addons, so I can use familiar shortcuts from vim in every code editor.

Vim, the ancient text editor, that used to edit text files in terminal, is being used by a lot of people. Me including. Why should anyone use this old, terminal based text editor, while there are beautiful window based, fashionable and modern text editors out there? 

One of the best benefits of using vim is that I learned many of the vim shortcuts. And every other editor that I used has a vim addon. This allows me to use all vim shortcuts in every editor, without learning new shortcuts.

Example of vim add on for visual studio code

A little tip, use vim bootstrap to add some pre defined features to your vim. I added some personal addition on top of that , check them here.