hello here are two simple exercises in the C programming language...
exercise 1:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// create a char buffer with 500 characters
// ask the user to type a sentence (you can use gets() for that)
// count how many spaces are on the sentence.
int spacesCount(const char* targetString) {
int countSpaces = 0;
for (int i = 0; targetString[i] != '\0'; i++) {
if (targetString[i] == ' ') {
countSpaces++;
}
}
return countSpaces;
}
// make a spacesCount2 function, but this time using strchr() to locate the space.
int spacesCount2(const char* targetString) {
int countSpaces = 0;
char* pSpace = strchr(targetString, ' ');
while (pSpace != 0) {
pSpace = strchr(pSpace+1, ' ');
countSpaces++;
}
return countSpaces;
}
int spacesCount3(const char* targetString) {
int countSpaces = 0;
printf( "Str start = %p\n" , targetString);
while ( (targetString = strchr(targetString, ' ')) != 0 ) {
printf( "Space ptr = %p '%s'\n" , targetString, targetString);
countSpaces++ ; targetString++;
}
return countSpaces;
}
int main() {
char MyString[500] = "Hello, Nice to meet you, what can i do for you?";
puts(MyString);
//gets(MyString);
// int result = spacesCount(MyString);
printf("there are %i spaces in this char array\n", spacesCount(MyString));
printf("there are %i spaces in this char array\n", spacesCount2(MyString));
printf("there are %i spaces in this char array\n", spacesCount3(MyString));
return 0;
}
2nd exercise:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// write a function that takes a string and returns the number that is inside the string
// spaces at START should be ignored
// finding a character that is not a number ends the function (returning the number obtained so far)
int toInt(const char* myStr) {
int number = 0, foundDigit = 0;
for (int i = 0 ; myStr[i] != '\0'; i++) {
if (myStr[i] == ' ') {
if (foundDigit) {
break;
}
continue;
}
if (myStr[i] < '0' || myStr[i] > '9') {
break;
}
foundDigit = 1;
number = (number * 10) + (myStr[i] - '0');
}
return number;
}
int main() {
char MyNumber[] = " 456 8!9";
// char MyNumber[] = " 47";
printf("The Number is %i", toInt(MyNumber));
return 0;
}
another two exercises in C regarding dynamic strings
first exercise:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// 1 1 0 0 1 1 1 0 0 0 0 1 1 1 0 0 1 1 1 1 = 2000mb of memory
// 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0
// 1200mb in use
// 800mb free
// but as a single block you can only allocate 400mb
// and you can reallocate the last 400mb to 500mb because there isnt 500mb free elsewhere
// but you can reallocate the the first block of 300mb up to 700mb!
// and you can reallocate the second block of 300mb up to 500mb (because they dont need to move around)
// you have 2gb of address space
// and you have a block that 1gb of sizeof
// if you try to reallocate this to 1.5gb it will fail
// because the "realloc" must first allocate the new space (1.5gb+1gb)
// then copy from the old space to the new space
// then free the old space
#include <windows.h>
int main() {
SetPriorityClass( GetCurrentProcess() , REALTIME_PRIORITY_CLASS );
char Buffer[4096];
char *FullText = NULL;
int FullTextLen = 0;
while (1) {
printf("Type a sentence: ");
gets(Buffer);
int len = strlen(Buffer);
char* NewPtr = realloc( FullText , sizeof(char)*(FullTextLen+len+1) );
if (!NewPtr) {
puts("Failed to reallocate!!!!");
} else {
FullText = NewPtr;
}
DWORD dwStart = GetTickCount();
for( int N = 0 ; N < 1000000 ; N++ ) { strcpy( FullText+FullTextLen , Buffer ); }
printf("(strcpy Took %ims\n", GetTickCount()-dwStart);
dwStart = GetTickCount();
for( int N = 0 ; N < 1000000 ; N++ ) { memcpy( FullText+FullTextLen , Buffer , len+1 ); }
printf("memcpy Took %ims\n", GetTickCount()-dwStart);
#if 0
strcpy( FullText+FullTextLen , Buffer );
FullTextLen += len;
#else
memcpy( FullText+FullTextLen , Buffer , len+1 ); //+1 to copy the terminator
FullTextLen += len;
//FullText[FullTextLen]=0 (if copying is not an option then manually setting the terminator)
#endif
printf("%p = (%i)'%s'\n",FullText, FullTextLen, FullText);
}
return 0;
}
2nd exercise - dynamic string structure and functions (string lib)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
typedef struct string {
char* data;
int len;
} string;
// s - string container pointer, if passed as NULL then we allocate the container
// text - the text that will be initialized on our string container
// len - the length of the text pointed by 'text' if -1 assume it's a C string and we must use strlen() to grab the actual length
// if the length is NOT -1 we can't assume that the string ends with a \0 terminator.
// returns the string* if success or return NULL if failed (if a string* is passed (not NULL) then the return value will be that same string* pointer)
// if the function fails allocating the memory for the text, but it allocated the header for the string* then it must return NULL, but it must free that allocated header
string* strInit( string* s , char* text , int len ) {
bool allocheader = false;
// handling the header
if (s == NULL) {
s = malloc(sizeof(*s));
allocheader = true;
if (!s) {
return NULL;
}
}
// if len parameter is -1 (smaller then 0)
if (len < 0) {
len = strlen(text);
}
// this allocates space for the text and clean up if fails
s->data = malloc(len + 1);
if (!s->data) {
if (allocheader) {
free(s);
}
return NULL;
}
//this copy the data from char to the string
memcpy(s->data, text, len);
s->data[len] = 0; // this setup the 0 terminator at the end of the string
s->len = len; // set up the string length to the length of the char array
return s;
/* // my first try - crash and burned!!!
if (string != NULL) {
return string*;
}
if (len == -1) {
int stringLen = strlen(text);
char* stringPtr = realloc(text, sizeof(char)*stringLen+1);
s.data = stringPtr
s.Len = stringLen
return s
*/
}
// simplification that always allocates the header and always calculates the size from the immediate text (should be freed with strDelete);
#define strNew( _text ) strInit( NULL , _text , -1 );
// s - string container to clean up
// free the s->data memory and zero the contents of the header(container)
void strClean( string* s ) {
if (!s) {
return ;
}
if (s->data) {
free(s->data);
}
memset(s, 0, sizeof(*s));
}
// s - string container to cleanup AND free the container
// calls the strCLean to cleanup the string, and then use free to deallocate the header(container)
void strDelete( string* s) {
if (!s) {
return ;
}
strClean(s);
free(s);
}
int main() {
string MyString;
strInit( &MyString , "Hello" , - 1);
/*
char Buffer[4096];
char *FullText = NULL;
int FullTextLen = 0;
printf("Type a sentence: ");
gets(Buffer);
*/
printf( "Before Clean = '%s'\n" , MyString.data );
strClean( &MyString );
printf( "After Clean = '%s'\n" , MyString.data );
string *MyName = strNew( "Greg" );
puts( MyName->data );
strDelete( MyName );
return 0;
}