项目作者: vicmoh

项目描述 :
A dynamic string API to make string coding much easier in C similar to other modern languages
高级语言: C
项目地址: git://github.com/vicmoh/dynamic-string-api.git
创建时间: 2018-05-23T00:16:04Z
项目社区:https://github.com/vicmoh/dynamic-string-api

开源协议:MIT License

下载


Dynamic String API for C

A dynamic string API to make string coding much easier in C similar to other modern languages.
Please note, this library is currently only available for Linux.

Installation of API

1. Download

  1. git clone https://github.com/vicmoh/dynamic-string-api

2. Run

To compile and run the program type make or make valgrind on terminal program directory.
Place any of your .c files in src folder and .h in include.
No need to change the makefile.
Any files you placed in scr, include, lib will automatically compile and run the program when make is invoked.

  1. make

Directory Structure

Any C file should be placed under the src folder.
There is already main.c where you can start your project.

  1. src/main.c

Any shared or static libraries goes under the lib folder.

  1. lib/DynamicString.a
  2. lib/DynamicString.so

Your header .h files must be inside the include folder.

  1. include/DynamicString.h
  2. include/Tokenizer.h
  3. include/ArrayMap.h
  4. include/LinkedList.h

The bin folder is where the executable files goes to.
By default, runProgram will be your executable when make is invoked on the terminal.

  1. bin/runProgram

If you already have a project, you can add the API to your makefile.
Copy and paste the DynamicString.a and the header file you want to use to your project.

How to Use the Dynamic String API

String Usage

Simply, any tag inside $( ) is a string.
Higher level languages uses + symbol to assign multiple strings together.
In comparison, you can assign similar way using , to represent different strings inside the string tag.
Similar to other languages, the function print( ) is also available using the string tag format which will output to the console.

To declare a string:

  1. String test = $("Hello world!");
  2. print("print1: ", test);
  3. /************ output ************
  4. print1: Hello world!
  5. *********************************/

You can also assign string with other string. As long as it is in the string tag it will return a dynamically allocated combined string:

  1. String name = $("Vic");
  2. String sayHello = NULL;
  3. String toBeAssigned = NULL;
  4. sayHello = $("Hello my name is ", name, ", how is it going?");
  5. toBeAssigned = $(sayHello);
  6. print("print2: ", toBeAssigned);
  7. /************ output ************
  8. print2: Hello my name is Vic, how is it going?
  9. *********************************/

Number in String

Number variables such as int or double in string tag $( ) must use _( ) or it will not compile.
You can also use constant numbers inside instead of variables such as _(3):

  1. const int age = 8;
  2. String sayYourCodeYears = $("I have been coding for ", _(age), " years.");
  3. print("print", _(3) , ": ", sayYourCodeYears);
  4. /************ output ************
  5. print3: I have been coding for 8 years.
  6. *********************************/

Another example:

  1. int num1 = 2;
  2. int num2 = 2;
  3. String addition = $(_(num1), " plus ", _(num2), " is ", _(num1+num2));
  4. print("print4: ", addition, " minus 1 that's 3 quick math.");
  5. /************ output ************
  6. print4: 2 plus 2 is 4 minus 1 that's 3 quick math.
  7. *********************************/

Here’s another example to print with decimal places on numbers.
The first argument in _dec( ) is the value, and the second is the number of decimal places to show:

  1. const double pi = 3.14159;
  2. String sayPiInDecimal = $("What is the Pi number? ", _dec(pi, 2), " is the number, duh!");
  3. print("print", _dec(5, 0), ": ", sayPiInDecimal);
  4. /************ output ************
  5. print5: What is the Pi number? 3.14 is the number, duh!
  6. *********************************/

Memory Management

Previously this is how we use to code string in C. We had to use an array of chars.

The code below is how we manipulate char array in C, problem with this is that the size is constant and it could not hold string longer than 30. So what if it happens to be a longer string?

Another way to fix the problem is to create a dynamic char array by mallocing and then reallocing to a bigger size when we need to hold more char. So, we have to keep track of the size and it can be difficult to manage.

  1. // Dynamically char size previously how we use to code
  2. char* sayYourName = malloc(sizeof(char*)*30);
  3. char* name = malloc(sizeof(char*)*30);
  4. strcpy(name, "Jeff");
  5. strcpy(sayYourName, "My name is ");
  6. strcat(sayYourName, name);
  7. strcat(sayYourName, ".");
  8. printf("%s\n", sayYourName);
  9. // And when we need more memory we can just realloc the size
  10. char* sayYouName = realloc(sayYourName, sizeof(char*)*50)
  11. /************ output ************
  12. My name is Jeff.
  13. *********************************/

The string tag $( ) is a simpler form of dynamic chars in C which will adjust accordingly based on the string size. As a result, there is no need to keep track of the memory size of the char array, it will adjust dynamically based on the string size for you. Hence, making dynamic string simpler to code in C similar to other modern languages!

  1. // The new way of manipulating string in C
  2. String name = $("Jeff");
  3. String sayYourName = $("My name is ", name, ".");
  4. print(sayYourName);
  5. // In comparison to modern language like JavaScript
  6. var name = "Jeff";
  7. var sayYourName = "My name is " + name + ".";
  8. console.log(sayYourName);
  9. /************ output ************
  10. My name is Jeff.
  11. *********************************/

However, since string tag returns a dynamic allocated string,
every new string that has been created needs to be freed.
So don’t forget to free your string!

  1. // If DynamicString.h is used it will assign null after free when using free()
  2. free(test);
  3. free(name);
  4. free(multiply);
  5. free(sayHello);
  6. free(toBeAssigned);
  7. free(sayYourCodeYears);
  8. free(sayPiInDecimal);
  9. // You can also free multiple variables using delete() functions
  10. delete(test, name, addition, sayHello, sayYourCodeYears, sayPiInDecimal);

Tokenizer

You can also split string through the token object
which split the token into an array of tokens similar to Java:

  1. // You can use 'split()' or 'new_Token()' to create token object
  2. String toBeSplit = $("This string is going to be split into array of string");
  3. Token* token = new_Token(toBeSplit, " ");
  4. for(int x=0; x<token->length; x++){
  5. print("token[",_(x),"]: ", token_getTokenAt(toBeSplit, x));
  6. }//end for
  7. /************ output ************
  8. token[0]: This
  9. token[1]: string
  10. token[2]: is
  11. token[3]: going
  12. token[4]: to
  13. token[5]: be
  14. token[6]: split
  15. token[7]: into
  16. token[8]: array
  17. token[9]: of
  18. token[10]: string
  19. *********************************/
  20. delete(toBeSplit);
  21. Token_free(token);

Data Structure

The library also contains other data structure such as array, map or linked list.
It follows a standard to declare and access an object.
To initialize an object simply declare by: [objectType]* varName = new_[objectType]()

Every new object starts with new_ tag
and you can access the object method by: [objectTypeInLowerCase]_[functionName]()

Array

  1. // Declaring a new object. The parameter takes a function of what to free.
  2. // You can pass in NULL if you don't wont the array data to be freed.
  3. Array* listOfString = new_Array(string_free);
  4. // To add object to an array
  5. array_add(listOfString, $("first string") );
  6. // To add multiple object to an array
  7. array_addMultiple(listOfString,
  8. $("second string"),
  9. $("third string"),
  10. $("fourth string"),
  11. $("fifth string")
  12. );
  13. // You can also use 'for in' loop.
  14. // But the object struct must have length variable
  15. // such as map, linked list, and array from the library.
  16. for_in(x, listOfString){
  17. print("index[",_(x),"]: ", array_get(listOfString, x));
  18. }//end for
  19. /************ output ************
  20. index[0]: first string
  21. index[1]: second string
  22. index[2]: third string
  23. index[3]: fourth string
  24. index[4]: fifth string
  25. *********************************/
  26. array_free(listOfString);

Map

  1. // Declaring a new object. The param takes a function of what to free.
  2. // You can pass in NULL if you don't wont the data to be freed.
  3. Map* cars = new_Map(string_free);
  4. String ferrariKey = $("Ferrari");
  5. String hondaKey = $("Honda");
  6. // Adding to the map
  7. map_add(cars, ferrariKey, $("Price of a ", ferrariKey, ": $300,000"));
  8. map_add(cars, hondaKey, $("Price of a ", hondaKey, ": $20,000"));
  9. // Get the data by passing the key and print to console
  10. print(map_get(cars, "Ferrari"));
  11. print(map_get(cars, "Honda"));
  12. /************ output ************
  13. Price of a Ferrari: $300,000
  14. Price of a Honda: $20,000
  15. *********************************/
  16. delete(ferrariKey, hondaKey);
  17. map_free(cars);

Other Advance Usage

The DynamicString.h also contain preprocessors of another way to make objects:

  1. CLASS(Point,
  2. // To declare instance variables
  3. // you must add "," comma at the end
  4. long double x;
  5. long double y;
  6. String toString,
  7. // Use "this" to access the instance in constructor
  8. // don't forget "," comma at the end
  9. CONSTRUCTOR(Point, (long double x, long double y),
  10. this->x = x;
  11. this->y = y;
  12. this->toString = $("");
  13. ),//end constructor
  14. // Destructor function
  15. void point_free(void* obj){
  16. Point* this = obj;
  17. if(this == NULL) return;
  18. delete(this->toString, this);
  19. }//end func
  20. // Function that return string for point
  21. String point_toString(Point* this){
  22. free(this->toString);
  23. this->toString = $("position: ", _(this->x), ", ", _(this->y));
  24. return this->toString;
  25. }//end func
  26. // Getter function of instance x
  27. int point_getX(Point* this){
  28. return this->x;
  29. }//end func
  30. // Getter function of instance y
  31. int point_getY(Point* this){
  32. return this->y;
  33. }//end func
  34. // Setter function that multiply the position value
  35. void point_multiplier(Point* this, int multiplier){
  36. this->x = this->x * multiplier;
  37. this->y = this->y * multiplier;
  38. }//end func
  39. );//end class

Usage example 1:

  1. // To declare point object
  2. Point* position = new_Point(10, 15);
  3. print(point_toString(position));
  4. // Multiply the point value by 2
  5. point_multiplier(position, 2);
  6. print(
  7. "the new x value is ", _(point_getX(position)), "\n",
  8. "and the new y value is ", _(point_getY(position))
  9. );
  10. /************ output ************
  11. position: 10, 15
  12. the new x value is 20
  13. and the new y value is 30
  14. *********************************/
  15. point_free(position);

Usage example 2:

  1. // Add multiplier points to the array
  2. Array* points = new_Array(point_free);
  3. array_addMultiple(points,
  4. new_Point(10, 10),
  5. new_Point(20, 20),
  6. new_Point(30, 30),
  7. new_Point(40, 40)
  8. );
  9. // Loop the array and print the point object
  10. for_in(x, points){
  11. print(point_toString(array_get(points, x)));
  12. }//end for
  13. /************ output ************
  14. position: 10, 10
  15. position: 20, 20
  16. position: 30, 30
  17. position: 40, 40
  18. *********************************/
  19. array_free(points);