RetroCoders Community

Help => Beginners => Topic started by: ron77 on May 30, 2023, 04:36 PM

Title: C programming exercises
Post by: ron77 on May 30, 2023, 04:36 PM
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;
}
Title: Re: C programming exercises
Post by: ron77 on Jun 01, 2023, 04:03 PM
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;
}