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
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 asint* 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 )