-
-
Save ThePhD/feb657c0a6e9745fc417 to your computer and use it in GitHub Desktop.
Because why the hell not
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> // getchar | |
#include <stdbool.h> // bool, true/false | |
#include <stdlib.h> // Malloc | |
typedef ptrdiff_t intz; | |
typedef size_t intuz; | |
typedef struct string_ { | |
char* data; | |
intz len; | |
} string; | |
// This is just sugar syntax for a pointer | |
// Copies an existing string pointer, rather than referencing it | |
string string_create( char str[] ) { | |
string s; | |
s.data = 0; | |
s.len = 0; | |
if ( str == 0 ) { | |
// Ensure there is always a string, | |
// just that it's the empty c-style string "" | |
s.data = malloc( 1 ); | |
s.len = 0; | |
s.data[ 0 ] = '\0'; | |
return s; | |
} | |
char* strbegin = str; | |
while ( str[0] != '\0' ) { | |
++s.len; | |
++str; | |
} | |
s.data = malloc( s.len + 1 ); | |
str = strbegin; | |
for ( intz i = 0; i < s.len; ++i ) { | |
s.data[ i ] = str[ i ]; | |
} | |
// Always null terminate | |
s.data[ s.len ] = '\0'; | |
return s; | |
} | |
string string_copy( string copy ) { | |
string s; | |
if ( copy.data == 0 || copy.len == 0 ) { | |
// Zero copy (empty string always) | |
s.data = malloc( 1 ); | |
s.data[ 0 ] = '\0'; | |
s.len = 0; | |
} | |
s.data = malloc( copy.len + 1 ); | |
s.len = copy.len; | |
for ( intz i = 0; i < copy.len; ++i ) { | |
s.data[ i ] = copy.data[ i ]; | |
} | |
// Always null terminate | |
s.data[ s.len ] = '\0'; | |
return s; | |
} | |
string string_free( string s ) { | |
free( s.data ); | |
s.data = 0; | |
// We don't really need to do this | |
// Since we're using "value semantics" (not really) | |
// But why not? | |
s.len = 0; | |
return s; | |
} | |
void string_uppercase( string s ) { | |
// Not unicode safe... but we're only doing ASCII! :D | |
for ( intz i = 0; i < s.len; ++i ) { | |
char c = s.data[ i ]; | |
if ( c >= 'a' && c <= 'z' ) { | |
s.data[ i ] -= 32; | |
} | |
} | |
} | |
string get_line( ) { | |
char buffer[ 1024 ] = { 0 }; | |
char* bufferptr = buffer; | |
while ( true ) { | |
int c = getchar( ); | |
if ( c == EOF || c == '\n' ) { | |
bufferptr[ 0 ] = '\0'; | |
break; | |
} | |
bufferptr[ 0 ] = c; | |
++bufferptr; | |
if ( bufferptr == &buffer[ 1024 ] ) { | |
// TODO: line is longer than 1024 characters | |
// panic or build a bigger string or something | |
} | |
} | |
return string_create( buffer ); | |
} | |
int main( ) { | |
// Get the line | |
string s = get_line(); | |
// Copy the string to have something to work with | |
// Potential to do: print lowercase, uppercase it, print uppercase. | |
// Saves on copy | |
string su = string_copy( s ); | |
// Uppercase it | |
string_uppercase( su ); | |
// Print the value | |
printf( "Lowercase string: %s\nUppercase string: %s", s.data, su.data ); | |
// Proper cleanup since there's no expections or RAII | |
s = string_free( s ); | |
su = string_free( su ); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment