C
December 8, 2018 — 18:52

Author: silver  Category: dev  Comments: Off

IDE/Editor

  • Eclipse (CDT)
  • VS Code (MS C extensions)
  • Vim

Formatting:

1TBS of course ;)

Setup vi manually:

set noai tabstop=8 shiftwidth=8 softtabstop=8 noexpandtab

or use modeline in file:

/* vim: set noai tabstop=8 shiftwidth=8 softtabstop=8 noexpandtab: */

 

Strings

char greeting[6] = {'H', 'e', 'l', 'l', 'o', '\0'};
char str[12] = "Hello World";
char str[0] = '\0';
char buf[];

copy: strcpy(str2, str1)
concat: strcat(str1, str2)
length: strlen(str)
duplicate: ptr = strdup(str)
substring: strstr(str1, str2)
extract: strsep(*strptr, delimstr)

strstr():

locate subscring

or: “check if ‘sent’ contains ‘word'”

if(strstr(sent, word) != NULL) //..or skip NULL check

strsep():

  • extract token
  • or: “split substring using delim”
  • like deprecated strtok()
while((found = strsep(&string,",")) != NULL)

Things to remember

  • set it before using it (initialize)
  • strings are char arrays terminated by \0
  • strings in double quotes are auto terminated by \0
  • strcpy : watch out for buffer overruns with long strings
  • use : checks, char buf[1024], \0 term, malloc(strlen(str) + xx)
  • buf[] has no size and no space allocated
  • convert int to string: itoa, sprintf, snprintf(buf, 10, "%d", num);

tutorialspoint.com/cprogramming/c_strings.htm

Print

printf outputs to stdout stream
fprintf goes to a file handle FILE*
sprintf goes to a buffer you allocated (char*)

printf("This is a str: %s\n", str);
fprintf(fh, "log: %s", str);
sprintf(buf, "%s %s", str1, str2);

int: %d
long int: %ld
long long int: %lld
unsigned long long int: %llu

“%s” format specifier for printf always expects a char* argument

Pointers

// ptr is going to store address of integer value
int i = 20;
int *ptr;
                Operator        Operator Name           Purpose
*ptr            *               Value at Operator       gives Value stored at particular address
type* ptr;                      Same                    Same
&ptr            &               Address Operator        gives Address of Variable
**ptr                           Double Pointer          declares a Pointer to a Pointer
  • using *ptr is actually the first element (not its address)
  • while int *var is the same as int* var, *var is better/more clear to use
  • initialize (NULL or valid address)

Extern

  • tell compiler variable is declared elsewhere
  • use only in one place

example.h:

extern int global_variable;

example.c:

#include "example.h"
int global_variable = 1337;

example2.c:

#include "example.h"
void use_it(void)
{
    printf("Global variable: %d\n", global_variable++);
}

Compiler messages

warning: implicit declaration of function 'function' [-Wimplicit-function-declaration]

You are using a function for which the compiler has not seen a declaration (“prototype”) yet.

int main()
{
    fun(2, "21"); /* The compiler has not seen the declaration. */
    return 0;
}

int fun(int x, char *p)
{
    /* ... */
}

You need to declare your function before main, like this, either directly or in a header:

int fun(int x, char *p);

From stackoverflow.com/a/8440833

Macros

ifdef : “if defined” (quelle surprise;)

#ifndef : if NOT defined

example.c:

#ifdef DEBUG
 printf("DEBUG: %s\n", dbgstuff);
#endif

gcc -DDEBUG -c

gcc.gnu.org/onlinedocs/cpp/Ifdef.html

Include guard

#ifndef : checks whether the given token has been #defined earlier in the file or in an included file; if not, it includes the code between it and the closing #else or, if no #else is present, #endif statement.

#ifndef : is often used to make header files idempotent by defining a token once the file has been included and checking that the token was not set at the top of that file.

example.h:

#ifndef _INCL_GUARD
#define _INCL_GUARD
#endif

cprogramming.com/reference/preprocessor/ifndef.html

Malloc

char *buf = (char *) malloc(bufferSize);

where bufferSize is the runtime result of some computation

Examples:

char *string = (char*)malloc(n+1 * sizeof(char));
size_t length = strlen(str1) + strlen(str2) + 1;
char *concat = malloc(sizeof(char) * length);
char* buffer = (char*)malloc(256);
rhost = (char *)malloc(sizeof(char)*128);
  • if allocatable buffer space is variable, use malloc instead of buf[1024]
  • when done use free: free(buf);
  • strdupe already does malloc, no malloc needed

Execute command

exec() & friends like execve

system("ls -la")

get output: popen()

FILE *fp = popen("ls -la", "r");
if (fp)
 fscanf(fp, "%100s", var);

-or-

 fgets(var, 100, fp);

Return

return 0 or 1:

int function {
 if (success) { return 0; }
 return 1;
}

return char* value:

char* function {
 char *buf;
 ...
 return buf;
}

(use malloc or buf[1024] and free)

Examples:

str functions (example):

printf ("\nDEBUG: strncmp %s %i\n", flist_getfilename(ftmp), strncmp(flist_getfilename(ftmp), ".mp3", 4));
printf ("\nDEBUG: strcmp %s %i\n", flist_getfilename(ftmp), strcmp(flist_getfilename(ftmp), ".mp3"));
printf ("\nDEBUG: strcasecmp %s %d\n", flist_getfilename(ftmp), strcasecmp(flist_getfilename(ftmp), ".mp3"));

more strcmp:

if (!strncmp(flist_getfilename(ftmp), ".mp3", 4))
if (strncmp(flist_getfilename(ftmp), ".mp3", 4) != 4 )







We use Matomo free and open source web analytics
We also use Jetpack WordPress.com Stats which honors DNT