News:

Welcome to RetroCoders Community

Main Menu

C programming exercises

Started by ron77, May 30, 2023, 04:36 PM

Previous topic - Next topic

ron77

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;
}

ron77

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;
}