Advertisement
dmilicev

c_strings_with_pointers_with_dynamic_memory_allocation.c

May 2nd, 2021 (edited)
1,024
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 17.27 KB
  1. /*
  2.     c_strings_with_pointers_with_dynamic_memory_allocation.c
  3.  
  4.     Updated: 2021.05.03  ,  by Dragan Milicev, https://www.facebook.com/dmilicev
  5.  
  6.     In C language string is actually a one-dimensional array of characters
  7.     which is terminated by a null character '\0'.
  8.  
  9. // returns the length of the string passed to it,
  10. // but not including the terminating null character '\0'.
  11. int my_strlen(char *str)
  12.  
  13. // Copies the string pointed by source (including the null character) to the destination.
  14. // The function itself extends string1 to have enough space for string2.
  15. // Returns the copied string.
  16. void safe_strcpy(char* destination, const char* source)
  17.  
  18. // String concatenation, concatenates string2 to string1.
  19. // The function itself extends string1 to have enough space to append string2.
  20. char *safe_strcat( char *string1, const char *string2 ){
  21.  
  22. // Returns a pointer to the first occurrence of the character c in the string str,
  23. // or NULL if the character is not found.
  24. char *my_strchr(const char *s, int ch)
  25.  
  26. // Returns index of the first occurrence of the character c in the string str,
  27. // or -1 if the character is not found.
  28. int my_strchr_index(const char *s, int ch)
  29.  
  30. // Finds the first occurrence of the substr in the str.
  31. // The terminating '\0' characters are not compared.
  32. char *my_strstr( char *str, char *substr )
  33.  
  34. // Inserts into string str char at position index pos_index
  35. char *insert_char_into_string( char *str, char ch, int pos_index )
  36.  
  37. // Inserts into string subject string insert at position index pos_index
  38. char *insert_string_into_string( char *str, const char *insert, int pos_index ){
  39.  
  40. // Compares strings str1 and str2. Returns value
  41. // > 0 if str1 is greater than st2,
  42. // = 0 if str1 is equal to str2,
  43. // < 0 if str1 is less than str2.
  44. int my_strcmp(const char *str1, const char *str2)
  45. Note:
  46. When strcmp compare the character c in string1 with the character C in string2.
  47. The character c is greater than the character C because the asscii value
  48. of character c is 99 and the asscii value of character C is only 67.
  49.  
  50. // String str from right to left divides, using the character ch, into groups of n elements
  51. char *str_divide_into_groups( char *str, char ch, int n ) {
  52.  
  53.  
  54.     You can find all my C programs at Dragan Milicev's pastebin:
  55.  
  56.     https://pastebin.com/u/dmilicev
  57.  
  58. */
  59.  
  60. #include <stdio.h>
  61. #include <stdlib.h>     // for malloc() and realloc()
  62. #include <string.h>
  63.  
  64. // Returns the length of the string passed to it,
  65. // but not including the terminating null character '\0'.
  66. int my_strlen(char *str){
  67.     char *first = str;  //
  68.     while( *str )
  69.         str++;
  70.     return str - first;
  71. }
  72.  
  73. // Copies the string pointed by source (including the null character) to the destination.
  74. // Safe means that the function itself extends destination to have enough space for source.
  75. // Returns the copied string.
  76. char *safe_strcpy( char *destination, const char* source ){
  77.     int i, j, destination_len=strlen(destination), source_len=strlen(source);
  78.  
  79.     // allocate sufficient space, reallocating memory size of destination for source
  80.     destination = (char *)realloc( destination, (size_t)(source_len+1)*sizeof(char) );
  81.     if( destination == NULL ) {
  82.         fprintf(stderr, "\n\n destination realloc() error! \n\n");
  83.         exit(EXIT_FAILURE);
  84.     }
  85.  
  86.     while (*destination++ = *source++); // copying...
  87.  
  88.     *(destination+i) = '\0';            // finish the destination
  89.     return destination;
  90. } // safe_strcpy()
  91.  
  92. // Inserts into string str char at position index pos_index
  93. char *insert_char_into_string( char *str, char ch, int pos_index ) {
  94.     int i, j, str_len=strlen(str), new_len;
  95.  
  96.     if( pos_index<0 || pos_index>str_len){
  97.         fprintf(stderr, "\n\n Function insert_char_into_string(), pos_index = %d not valid ! \n\n", pos_index);
  98.         return NULL;
  99.     }
  100.  
  101.     new_len = str_len + 1;              // +1 is for ch
  102.  
  103.     // allocate sufficient space, reallocating memory size, for exteneded str
  104.     str = (char *)realloc(str, (size_t)(new_len+1)*sizeof(char) );
  105.     if( str == NULL ) {
  106.         fprintf(stderr, "\n\n str realloc() error! \n\n");
  107.         exit(EXIT_FAILURE);
  108.     }
  109.  
  110.     *(str+str_len) = '*';               // delete '\0' at the end of the string str
  111.     *(str+new_len) = '\0';              // finish the extended string str on new_len
  112.     i = str_len - 1;                    // index i points to the end of the string str
  113.     j = new_len - 1;                    // index j points to the end of the extended string str
  114.  
  115.     while( i>=pos_index )               // from right to left until the pos_index is reached
  116.         *(str+j--) = *(str+i--);        // copy string characters and update indexes
  117.  
  118.     *(str+j--) = ch;                    // insert character ch on pos_index
  119.  
  120.     while( i>=0 )                       // to the end of the string str
  121.         *(str+j--) = *(str+i--);        // copy string characters and update indexes
  122.  
  123.     return str;
  124. } // insert_char_into_string()
  125.  
  126. // Inserts into string subject string insert at position index pos_index
  127. char *insert_string_into_string( char *str, const char *insert, int pos_index ){
  128.     int i, j, str_len=strlen(str), k=strlen(insert), new_len=str_len+k;
  129.  
  130.     if( pos_index<0 || pos_index>str_len){
  131.         fprintf(stderr, "\n\n Function insert_char_into_string(), pos_index = %d not valid ! \n\n", pos_index);
  132.         return NULL;
  133.     }
  134.  
  135.     // allocate sufficient space, reallocating memory size, for exteneded string str
  136.     str = (char *)realloc(str, (size_t)(new_len+1)*sizeof(char) );
  137.     if( str == NULL ) {
  138.         fprintf(stderr, "\n\n str realloc() error! \n\n");
  139.         exit(EXIT_FAILURE);
  140.     }
  141.  
  142.     *(str+str_len) = '*';               // delete '\0' at the end of the string str
  143.     *(str+new_len) = '\0';              // finish the extended string str on new_len
  144.  
  145.     i = str_len - 1;                    // index i points to the end of the string str
  146.     j = new_len - 1;                    // index j points to the end of the extended string str
  147.     k--;                                // k becomes an index
  148.  
  149.     while( j > pos_index+k )            // from right to left until the pos_index+k is reached
  150.         *(str+j--) = *(str+i--);        // copy string characters and update indexes
  151.  
  152.     while( k >= 0 )                     // from right to left until the end of string insert
  153.         *(str+j--) = *(insert+k--);     // copy characters of string insert and update indexes
  154.  
  155.     while( i >= 0 )                     // to the end of the string str
  156.         *(str+j--) = *(str+i--);        // copy string characters and update indexes
  157.  
  158.     return str;
  159. } // insert_string_into_string()
  160.  
  161. // Compares strings str1 and str2. Returns value
  162. // > 0 if str1 is greater than st2,
  163. // = 0 if str1 is equal to str2,
  164. // < 0 if str1 is less than str2.
  165. int my_strcmp(const char *str1, const char *str2){
  166.     while( *str1 ){
  167.  
  168.         if (*str1 != *str2) // if characters differ, or end of the second string is reached
  169.             break;
  170.  
  171.         str1++;                         // move to the next pair of characters
  172.         str2++;
  173.     }
  174.     // return the ASCII difference after converting `char*` to `unsigned char*`
  175.     return *(const unsigned char*)str1 - *(const unsigned char*)str2;
  176. } // my_strcmp()
  177.  
  178. // String concatenation, concatenates string2 to string1.
  179. // Safe means that the function itself extends string1 to have enough space to append string2.
  180. // Returns the concatenated string.
  181. char *safe_strcat( char *string1, const char *string2 ){
  182.     int i, j, string1_len=strlen(string1), string2_len=strlen(string2);
  183.  
  184.     // allocate sufficient space, reallocating memory size, for exteneded string1
  185.     string1 = (char *)realloc( string1, (size_t)(string1_len+string2_len+1)*sizeof(char) );
  186.     if( string1 == NULL ) {
  187.         fprintf(stderr, "\n\n string1 realloc() error! \n\n");
  188.         exit(EXIT_FAILURE);
  189.     }
  190.  
  191.     i = string1_len;                    // index i points to the '\0' at the end of the string1
  192.     j = 0;                              // index j points to the begin of the string2
  193.  
  194.     while( *(string2+j) )               // for all string2
  195.         *(string1+i++) = *(string2+j++);// after string1, copy string2 characters and update indexes
  196.  
  197.     *(string1+i) = '\0';                // finish the string1
  198.     return (string1);
  199. } // safe_strcat()
  200.  
  201. // Returns a pointer to the first occurrence of the character c in the string str,
  202. // or NULL if the character is not found.
  203. char *my_strchr(const char *s, int ch){
  204.     do {
  205.         if (*s == ch)
  206.             return (char*)s;
  207.     } while (*s++);
  208.     return (0);
  209. } // my_strchr()
  210.  
  211. // Returns index of the first occurrence of the character c in the string str,
  212. // or -1 if the character is not found.
  213. int my_strchr_index(const char *s, int ch){
  214.     int i=0;
  215.     do {
  216.         if (*s == ch)
  217.             return (i);
  218.         i++;
  219.     } while (*s++);
  220.     return (-1);
  221. } // my_strchr_index()
  222.  
  223. // Finds the first occurrence of the substr in the str.
  224. // The terminating '\0' characters are not compared.
  225. char *my_strstr( char *str, char *substr ){
  226.     char *begin;
  227.     char *pattern;
  228.  
  229.     while(*str){
  230.         begin = str;
  231.         pattern = substr;
  232.         // if first character of substr match, check the whole str
  233.         while( *str && *pattern && *str == *pattern ){
  234.             str++;
  235.             pattern++;
  236.         }
  237.         // if complete substr match, return starting address
  238.         if( !*pattern )
  239.             return begin;
  240.         str = begin + 1; // increment main sting
  241.     }
  242.     return NULL;
  243. } // my_strstr()
  244.  
  245. // Finds the first occurrence of the substr in the str.
  246. // The terminating '\0' characters are not compared.
  247. // Returns index of the first occurrence of the substr in the str,
  248. // or -1 if the substr is not found.
  249. int my_strstr_index( char *str, char *substr ){
  250.     int i=0;
  251.     char *begin;
  252.     char *pattern;
  253.  
  254.     while(*str){
  255.         begin = str;
  256.         pattern = substr;
  257.         // if first character of substr match, check the whole str
  258.         while( *str && *pattern && *str == *pattern ){
  259.             str++;
  260.             i++;
  261.             pattern++;
  262.         }
  263.         // if complete substr match, return starting index
  264.         if( !(*pattern) )
  265.             return ( i - strlen(substr) );
  266.  
  267.         str = begin + 1; // increment main sting
  268.         i++;
  269.     }
  270.     return (-1);
  271. } // my_strstr_index()
  272.  
  273. // String str from right to left divides, using the character ch, into groups of n elements
  274. char *str_divide_into_groups( char *str, char ch, int n ) {
  275.     int i, j, str_len=strlen(str), new_len, counter, n_groups, n_rest, n_dots;
  276.  
  277.     if( n<=0 || n>str_len){
  278.         fprintf(stderr, "\n\n Function divide_the_string_into_groups(), n = %d not valid ! \n\n", n);
  279.         return NULL;
  280.     }
  281.  
  282.     n_groups = str_len / n;             // we calculate n_groups, number of groups of n elements
  283.     n_rest   = str_len % n;             // we calculate n_rest, remaining elements after all groups
  284.  
  285.     if( n_rest == 0 )                   // we calculate n_dots, number of dots
  286.         n_dots = n_groups - 1;
  287.     else
  288.         n_dots = n_groups;
  289.  
  290.     new_len = str_len + n_dots;         // we calculate new_len of extended string str
  291.  
  292.     // allocate sufficient space, reallocating memory size new_len, for exteneded str
  293.     str = (char *)realloc(str, (size_t)(new_len+1)*sizeof(char) );
  294.     if( str == NULL ) {
  295.         fprintf(stderr, "\n\n str realloc() error! \n\n");
  296.         exit(EXIT_FAILURE);
  297.     }
  298.  
  299.     *(str+str_len) = '*';               // delete '\0' at the end of the string str
  300.     *(str+new_len) = '\0';              // finish the extended string str on new_len
  301.     i = str_len - 1;                    // index i points to the end of the string str
  302.     j = new_len - 1;                    // index j points to the end of the extended string str
  303.     while( i>=0 ){                      // from end to beginning of string str
  304.         while( n_groups>0 ){            // for all n_groups groups
  305.             counter = 0;                // reset counter for n elements in the group
  306.             while(counter++ < n)        // for all n elements in the group, count elements in group
  307.                 *(str+j--) = *(str+i--);// update indexes
  308.             *(str+j--) = '.';           // after the group is completed we add a character ch (dot)
  309.             n_groups--;                 // count groups
  310.         }
  311.         while( n_rest-- > 0 )           //for all remaining elements after all groups
  312.             *(str+j--) = *(str+i--);    // update indexes
  313.     }
  314.     return str;
  315. } // str_divide_into_groups()
  316.  
  317.  
  318. int main(void){
  319.     char initial_string[]="abc1234567812345678";
  320.     char initial_string2[]="ab1234567812345678";
  321.     char ins_str[]="def";
  322.     char ch='.';
  323.     char ch1='3';
  324.     char *str;
  325.     char *str1;
  326.     int index_of_position=3;
  327.     int i;
  328.  
  329.     str1 = (char*)malloc( (strlen(initial_string)+1)*sizeof(char) );    // allocate sufficient space
  330.     if( str1 == NULL ) {
  331.         fprintf(stderr, "\n\n str1 malloc() error! \n\n");
  332.         exit(EXIT_FAILURE);
  333.     }
  334.  
  335.     printf("\n\n -------  my_strlen()  ----------------------------------- \n\n");
  336.  
  337.     strcpy(str1,initial_string);
  338.     printf("\n str1 = |%s| \n", str1);
  339.     printf("\n my_strlen(str1) = |%d| \n", my_strlen(str1) );
  340.  
  341.     printf("\n\n -------  my_strchr_index()  ----------------------------- \n\n");
  342.  
  343.     strcpy(str1,initial_string);
  344.     printf("\n str1 = |%s| \n", str1);
  345.     printf("\n ch1 = |%c| \n", ch1);
  346.     i = my_strchr_index(str1, ch1);
  347.     printf("\n i  = |%d| \n", i);
  348.     printf("\n String after |%c| is |%s| \n", ch1, str1+i );
  349.  
  350.     printf("\n\n -------  my_strchr()  ----------------------------------- \n\n");
  351.  
  352.     strcpy(str1,initial_string);
  353.     printf("\n str1 = |%s| \n", str1);
  354.     printf("\n ch1 = |%c| \n", ch1);
  355.     str1 = my_strchr(str1, ch1);
  356.     printf("\n String after |%c| is |%s| \n", ch1, str1 );
  357.  
  358.  
  359.     str = (char*)malloc( (strlen(initial_string)+1)*sizeof(char) ); // allocate sufficient space
  360.     if( str == NULL ) {
  361.         fprintf(stderr, "\n\n str malloc() error! \n\n");
  362.         exit(EXIT_FAILURE);
  363.     }
  364.  
  365.  
  366.     printf("\n\n -------  safe_strcpy()  --------------------------------- \n\n");
  367.  
  368.     *str = '\0';                                    // we empty str
  369.     printf("\n destination  = |%s| \n", str);
  370.     printf("\n source       = |%s| \n", "This is a string to be copied.");
  371.     safe_strcpy(str, "This is a string to be copied.");
  372.     printf("\n destination  = |%s| \n", str);
  373.  
  374.     printf("\n\n -------  my_strstr()  ----------------------------------- \n\n");
  375.  
  376.     strcpy(str,initial_string);
  377.     printf("\n str = |%s| \n", str);
  378.     strcpy(str1,"678");
  379.     printf("\n str1 = |%s| \n", str1);
  380.     printf("\n String after |%s| is |%s| \n", str1, my_strstr(str,str1) );
  381.  
  382.     printf("\n\n -------  my_strstr_index()  ----------------------------- \n\n");
  383.  
  384.     strcpy(str,initial_string);
  385.     printf("\n str = |%s| \n", str);
  386.     strcpy(str1,"123");
  387.     printf("\n str1 = |%s| \n", str1);
  388.     i = my_strstr_index(str,str1);
  389.     printf("\n index i = %d \n", i );
  390.     printf("\n String after |%s| is |%s| \n", str1, str+i );
  391.  
  392.     printf("\n\n -------  safe_strcat()  --------------------------------- \n\n");
  393.  
  394.     strcpy(str,initial_string);
  395.     printf("\n str1 = |%s| \n", str);
  396.     printf("\n str2 = |%s| \n", initial_string2);
  397.     safe_strcat(str, initial_string2);
  398.     printf("\n str1 + str2  = |%s| \n", str);
  399.  
  400.     printf("\n\n -------  insert_char_into_string()  --------------------- \n\n");
  401.  
  402.     strcpy(str,initial_string);
  403.     printf("\n Before,    str = |%s| \n", str);
  404.     insert_char_into_string(str, ch, index_of_position);
  405.     printf("\n After ch,  str = |%s| \n", str);
  406.  
  407.     printf("\n\n -------  insert_string_into_string()  ------------------- \n\n");
  408.  
  409.     strcpy(str,initial_string);
  410.     printf("\n Before,    str = |%s| \n", str);
  411.     printf("\n        ins_str = |%s| \n", ins_str);
  412.     printf("\n index_of_position = |%d| \n", index_of_position);
  413.     insert_string_into_string(str, ins_str, index_of_position);
  414.     printf("\n After,     str = |%s| \n", str);
  415.  
  416.     printf("\n\n -------  my_strcmp()  ----------------------------------- \n\n");
  417.  
  418.     strcpy(str,initial_string);
  419.     strcpy(str1,initial_string2);
  420.     printf("\n            str = |%s| \n", str);
  421.     printf("\n           str1 = |%s| \n", str1);
  422.     printf("\n my_strcmp() returns |%d| \n", my_strcmp(str,str1));
  423.     if ( my_strcmp(str,str1) > 0 )
  424.         printf("\n str is greater then str1. \n");
  425.     if ( my_strcmp(str,str1) == 0 )
  426.         printf("\n str is equal to str1. \n");
  427.     if ( my_strcmp(str,str1) < 0 )
  428.         printf("\n str is less then str1. \n");
  429.  
  430.     printf("\n\n -------  str_divide_into_groups()  ---------------------- \n\n");
  431.  
  432.     strcpy(str,initial_string);
  433.     printf("\n Before,    str = |%s| \n", str);
  434.     str_divide_into_groups(str, '.', 4);
  435.     printf("\n After div, str = |%s| \n", str);
  436.  
  437.     printf("\n\n -------  str_divide_into_groups()  ---------------------- \n\n");
  438.  
  439.     strcpy(str,initial_string2);
  440.     printf("\n Before,    str = |%s| \n", str);
  441.     str_divide_into_groups(str, '.', 8);
  442.     printf("\n After div, str = |%s| \n", str);
  443.  
  444.     printf("\n\n --------------------------------------------------------- \n\n");
  445.  
  446.  
  447.     free(str);  // we free up memory space because we used malloc()
  448.     return 0;
  449. } // main()
  450.  
Advertisement
RAW Paste Data Copied
Advertisement