• 纯C分割 字符串 devC++版本 vs各种奇怪的问题,


    上一篇的分割字符串,在少量字符的情况下可以正常用,但是 字串在几万的时候就有问题,不清楚是什么情况

    因此  去github上 https://github.com/jwlodek/csplit  看了下,感觉这个文件写的还可以,至少devc运行没有任何问题。但是 vs 会报错

    vs 修改了下   其中  477 行 会报错 主要是因为 

    DEV-C++使用的编译器是GCC,它允许使用变量作为数组的长度定义数组。
    VC的编译器不是GCC,它不允许你这样做。

      1 /********************************************************************************
      2  * MIT License
      3  *
      4  * Copyright (c) 2019 Jakub Wlodek
      5  *
      6  * Permission is hereby granted, free of charge, to any person obtaining a copy
      7  * of this software and associated documentation files (the "Software"), to deal
      8  * in the Software without restriction, including without limitation the rights
      9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     10  * copies of the Software, and to permit persons to whom the Software is
     11  * furnished to do so, subject to the following conditions:
     12  *
     13  * The above copyright notice and this permission notice shall be included in all
     14  * copies or substantial portions of the Software.
     15  *
     16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
     19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
     22  * SOFTWARE.
     23  *********************************************************************************/
     24 
     25  /**
     26   * @defgroup intern Internal
     27   * @brief Internal functions, not intended to be used by users
     28   * @defgroup set Setup
     29   * @brief Setup and Diagnostic functions used by csplit
     30   * @defgroup core csplit Core
     31   * @brief Core functions included in csplit
     32   */
     33 
     34   /**
     35    * A single-header C library for string manipulation and splitting.
     36    *
     37    * Author: Jakub Wlodek
     38    * Created: 02-Aug-2019
     39    */
     40 
     41 #define _CRT_SECURE_NO_WARNINGS
     42 #pragma warning(disable:4996)
     43    // Include guard - avoid redefinition
     44 #ifndef CSPLIT_H
     45 #define CSPLIT_H
     46 
     47 #ifdef __cplusplus
     48 extern "C" {
     49 #endif
     50 
     51     // some basic includes
     52 #include <stdio.h>
     53 #include <string.h>
     54 #include <stdlib.h>
     55 #include <ctype.h>
     56 
     57 #ifdef _MSC_VER
     58 # define _CSPLIT_FUNC static __inline
     59 #elif !defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L
     60 # define _CSPLIT_FUNC static __inline__
     61 #else
     62 # define _CSPLIT_FUNC static inline
     63 #endif
     64 
     65 /**
     66  * Enum type for error codes for csplit
     67  * @ingroup set
     68  */
     69     typedef enum CSPLIT_ERROR {
     70         CSPLIT_SUCCESS = 0,     /**< No Error */
     71         CSPLIT_TOO_SHORT = -1,    /**< Input string is too short */
     72         CSPLIT_NO_SUCH_INDEX = -2,    /**< Index out of range */
     73         CSPLIT_UNIMPLEMENTED = -3,    /**< Function unimplemented */
     74         CSPLIT_BUFF_EXCEEDED = -4,    /**< Buffer size exceeded */
     75     } CSplitError_t;
     76 
     77 
     78     /**
     79      * Struct for an individual string fragment result from csplit
     80      * @ingroup intern
     81      */
     82     typedef struct CSPLIT_FRAGMENT {
     83         char* text;                         /**< Text of the fragment. */
     84         struct CSPLIT_FRAGMENT* next;       /**< Next fragment in the linked list */
     85         struct CSPLIT_FRAGMENT* prev;       /**< Previous fragment in the linked list */
     86     } CSplitFragment_t;
     87 
     88 
     89     /**
     90      * Struct that stores the csplit linked list. Can be used as an arbitrary linked list
     91      * for strings, but is intended for use with csplit strtok replacement functions
     92      * @ingroup core
     93      */
     94     typedef struct CSPLIT_LIST {
     95         int num_elems;              /**< Number of elements in the list */
     96         CSplitFragment_t* head;     /**< Head of the linked list (first element) */
     97         CSplitFragment_t* tail;     /**< Tail of the linked list (last element) */
     98     } CSplitList_t;
     99 
    100 
    101     /* Function Declarations */
    102 
    103     _CSPLIT_FUNC
    104         CSplitList_t* csplit_init_list();
    105 
    106     _CSPLIT_FUNC
    107         void csplit_clear_list(CSplitList_t* list);
    108 
    109     _CSPLIT_FUNC
    110         CSplitError_t csplit_push_to_list(CSplitList_t* list, CSplitFragment_t* fragment, int buff_size);
    111 
    112     _CSPLIT_FUNC
    113         void csplit_print_list_info(CSplitList_t* list, FILE* fp);
    114 
    115 #ifdef CSPLIT_DEBUG
    116     _CSPLIT_FUNC
    117         void print_csplit_fragment_info(CSplitFragment_t* fragment, FILE* fp);
    118 #endif
    119 
    120     _CSPLIT_FUNC
    121         char* csplit_get_fragment_at_index(CSplitList_t* list, int index);
    122 
    123     _CSPLIT_FUNC
    124         CSplitError_t csplit_reverse_list(CSplitList_t* list);
    125 
    126     _CSPLIT_FUNC
    127         char* csplit_strip(char* input_str);
    128 
    129     _CSPLIT_FUNC
    130         char* csplit_remove_whitespace(char* input_str);
    131 
    132     _CSPLIT_FUNC
    133         int csplit_startswith(char* input_str, char* starts_with);
    134 
    135     _CSPLIT_FUNC
    136         int csplit_endswith(char* input_str, char* ends_with);
    137 
    138     _CSPLIT_FUNC
    139         CSplitError_t csplit_rstr(CSplitList_t* list, char* input_str, char* token, int max_splits);
    140 
    141     _CSPLIT_FUNC
    142         CSplitError_t csplit_str(CSplitList_t* list, char* input_str, char* token, int max_splits);
    143 
    144     _CSPLIT_FUNC
    145         CSplitError_t csplit_lim(CSplitList_t* list, char* input_str, char* token, int max_splits);
    146 
    147     _CSPLIT_FUNC
    148         CSplitError_t csplit(CSplitList_t* list, char* input_str, char* token);
    149 
    150     _CSPLIT_FUNC
    151         CSplitError_t rcsplit(CSplitList_t* output_list, char* input_str, char* token);
    152 
    153 
    154     /* Function Definitions */
    155 
    156 
    157     /**
    158      * @brief Function for initializing a csplit list
    159      * @ingroup set
    160      *
    161      * @params[in]: buff_size   -> user set buffer size. Make sure this is large enough for your largest fragment
    162      * @return: list            -> an allocated csplit list
    163      */
    164     _CSPLIT_FUNC
    165         CSplitList_t* csplit_init_list() {
    166         CSplitList_t* list = (CSplitList_t*)calloc(1, sizeof(CSplitList_t));
    167         list->num_elems = 0;
    168         return list;
    169     }
    170 
    171 
    172     /**
    173      * @brief Clears all memory for an allocated csplit list
    174      * @ingroup set
    175      *
    176      * @params[in]: list    -> a previously allocated csplit list to be freed
    177      */
    178     _CSPLIT_FUNC
    179         void csplit_clear_list(CSplitList_t* list) {
    180         CSplitFragment_t* current_fragment = list->head;
    181         while (current_fragment != NULL) {
    182             CSplitFragment_t* temp = current_fragment->next;
    183             free(current_fragment->text);
    184             free(current_fragment);
    185             current_fragment = temp;
    186         }
    187         free(list);
    188     }
    189 
    190 
    191     /**
    192      * @brief Function that pushes a new CSplitFragment to the end of the list, and allocates memory for the text,
    193      * with size list->BUFF_SIZE
    194      * @ingroup intern
    195      *
    196      * @params[out]: list       -> The list with fragment appended to the tail
    197      * @params[in]: fragment    -> fragment to append to the list. fragment->text will be allocated based on list->BUFF_SIZE
    198      */
    199     _CSPLIT_FUNC
    200         CSplitError_t csplit_push_to_list(CSplitList_t* list, CSplitFragment_t* fragment, int buff_size) {
    201         // first make sure neither is null
    202         if (list == NULL || fragment == NULL) {
    203             return CSPLIT_TOO_SHORT;
    204         }
    205         else {
    206             // then update the number of elements, and the pointers
    207             list->num_elems = list->num_elems + 1;
    208             if (list->head == NULL) {
    209                 list->head = fragment;
    210                 list->tail = fragment;
    211             }
    212             else {
    213                 list->tail->next = fragment;
    214                 fragment->prev = list->tail;
    215                 list->tail = fragment;
    216             }
    217             // allocate fragment text field
    218             fragment->text = (char*)calloc(1, buff_size);
    219         }
    220         return CSPLIT_SUCCESS;
    221     }
    222 
    223 
    224     /**
    225      * @brief Function that prints information about a csplit list
    226      * @ingroup set
    227      *
    228      * @params[in]: list    -> list for which to print info
    229      * @params[in]: fp      -> file pointer to print into.
    230      */
    231     _CSPLIT_FUNC
    232         void csplit_print_list_info(CSplitList_t* list, FILE* fp) {
    233         if (list == NULL || fp == NULL) return;
    234         fprintf(fp, "List contains %d elements
    ", list->num_elems);
    235         fprintf(fp, "Supports indexes -%d to %d.
    ", list->num_elems, list->num_elems - 1);
    236         CSplitFragment_t* current_fragment = list->head;
    237         while (current_fragment != NULL) {
    238             fprintf(fp, "--%s--
    ", current_fragment->text);
    239             current_fragment = current_fragment->next;
    240         }
    241     }
    242 
    243 
    244 #ifdef CSPLIT_DEBUG
    245     /**
    246      * @brief Function that prints information about a csplit fragment - intended for internal use only
    247      * @ingroup intern
    248      *
    249      * @params[in]: fragment    -> fragment for which to print info
    250      * @params[in]: fp          -> file pointer to print into
    251      */
    252     _CSPLIT_FUNC
    253         void print_csplit_fragment_info(CSplitFragment_t* fragment, FILE* fp) {
    254         if (fragment == NULL || fp == NULL) return;
    255         fprintf(fp, "Fragment has text %s
    ", fragment->text);
    256         if (fragment->next != NULL) fprintf(fp, "Fragment has next with text %s
    ", fragment->next->text);
    257         if (fragment->prev != NULL) fprintf(fp, "Fragment has prev with text %s
    ", fragment->prev->text);
    258     }
    259 #endif
    260 
    261 
    262     /**
    263      * @brief Function that returns the string fragment at a certain index in the list
    264      * @ingroup core
    265      *
    266      * @params[in]: list    -> list generated by csplit
    267      * @params[in]: index   -> index to search for (can be negative for getting at index from back of list)
    268      * @return: text        -> string at the given index or NULL if index out of range.
    269      */
    270     _CSPLIT_FUNC
    271         char* csplit_get_fragment_at_index(CSplitList_t* list, int index) {
    272         // convert index into absolute index (if negative);
    273         int target_index;
    274         if (index < 0) {
    275             target_index = index + list->num_elems;
    276         }
    277         else {
    278             target_index = index;
    279         }
    280         // if index is out of range return null
    281         if (list->num_elems <= target_index || target_index < 0) {
    282             return NULL;
    283         }
    284         else {
    285             // iterate over list until index found
    286             int counter = 0;
    287             CSplitFragment_t* current_fragment = list->head;
    288             while (counter < target_index) {
    289                 current_fragment = current_fragment->next;
    290                 counter++;
    291             }
    292             // return the text field
    293             return current_fragment->text;
    294         }
    295     }
    296 
    297 
    298     /**
    299      * @brief Function that reverses the list generated by csplit
    300      * @ingroup set
    301      *
    302      * @params[out]: list   -> list to reverse
    303      * @return: err         -> error code if there is an error
    304      */
    305     _CSPLIT_FUNC
    306         CSplitError_t csplit_reverse_list(CSplitList_t* list) {
    307         int i;
    308         // iterate over list and swap next and previous fields
    309         CSplitFragment_t* temp = list->head;
    310         for (i = 0; i < list->num_elems; i++) {
    311             CSplitFragment_t* temp2 = temp->next;
    312             temp->next = temp->prev;
    313             temp->prev = temp2;
    314             temp = temp2;
    315         }
    316         // swap head and tail
    317         temp = list->head;
    318         list->head = list->tail;
    319         list->tail = temp;
    320         return CSPLIT_SUCCESS;
    321     }
    322 
    323 
    324     /**
    325      * @brief Function that strips a given string into an output string. Will remove whitespace character:
    326      * 
    , 
    , 	, space will be removed from the start and end of each string.
    327      * @ingroup core
    328      *
    329      * @params[in]: input_str   -> the input string to strip
    330      * @return: output_str      -> the string with whitespace removed from the ends. Must be freed.
    331      */
    332     _CSPLIT_FUNC
    333         char* csplit_strip(char* input_str) {
    334         char* output_str;
    335         // check if input is null
    336         if (input_str == NULL)
    337             output_str = NULL;
    338         else {
    339             int len = strlen(input_str);
    340             char* end = input_str + len - 1;
    341             char* start = input_str;
    342             while (isspace(*start)) {
    343                 if (*start == '' || start == end) return NULL;
    344                 else start++;
    345             }
    346             while (isspace(*end))
    347                 end--;
    348 
    349             int buff_size = end - start + 1;
    350             output_str = (char*)calloc(1, buff_size + 1);
    351             strncpy(output_str, start, buff_size);
    352         }
    353         return output_str;
    354     }
    355 
    356 
    357     /**
    358      * @breifFunction that removes all whitespace characters of a given string into an output string.
    359      * Note that resulting char* must be free'd after it is no longer used
    360      * @ingroup core
    361      *
    362      * @params[in]: input_str   -> the input string to strip
    363      * @return: output_str      -> the string with whitespace removed.
    364      */
    365     _CSPLIT_FUNC
    366         char* csplit_remove_whitespace(char* input_str) {
    367         char* output_str;
    368         if (input_str == NULL)
    369             output_str = NULL;
    370         else {
    371             int len = strlen(input_str);
    372             output_str = (char*)calloc(1, len);
    373             int counter = 0;
    374             int output_counter = 0;
    375             // read through but don't copy whitespace
    376             while (counter < len) {
    377                 if (!isspace(input_str[counter])) {
    378                     output_str[output_counter] = input_str[counter];
    379                     output_counter++;
    380                 }
    381                 counter++;
    382             }
    383         }
    384         return output_str;
    385     }
    386 
    387 
    388     /**
    389      * @brief Function that checks if a given string starts with another given string.
    390      * @ingroup core
    391      *
    392      * @params[in]: input_str       -> string to check against
    393      * @params[in]: starts_with     -> string to try to match with start of input string
    394      * @return:     int             -> -2 if input is invalid, -1 if doesn't start with given string, or 0 if it does
    395      */
    396     _CSPLIT_FUNC
    397         int csplit_startswith(char* input_str, char* starts_with) {
    398         if (input_str == NULL || starts_with == NULL) return -2;
    399         else if (strstr(input_str, starts_with) == input_str) return 0;
    400         else return -1;
    401     }
    402 
    403 
    404     /**
    405      * @brief Function that checks if a given string ends with another given string.
    406      * @ingroup core
    407      *
    408      * @params[in]: input_str       -> string to check against
    409      * @params[in]: ends_with       -> string to try to match with end of input string
    410      * @return:     int             -> -2 if input is invalid, -1 if doesn't end with given string, or 0 if it does
    411      */
    412     _CSPLIT_FUNC
    413         int csplit_endswith(char* input_str, char* ends_with) {
    414         if (input_str == NULL || ends_with == NULL) {
    415             return -2;
    416         }
    417         else {
    418             int ewith_len = strlen(ends_with);
    419             int istr_len = strlen(input_str);
    420             if (ewith_len > istr_len) return -1;
    421             else if (strcmp(input_str + istr_len - ewith_len, ends_with) == 0) return 0;
    422             else return -1;
    423         }
    424     }
    425 
    426 
    427     /**
    428      * @brief Function that runs csplit on a particular string from the end of the input. Called if max_splits < 0
    429      * @ingroup intern
    430      *
    431      * @params[out]: list       -> split input string into this list structure
    432      * @params[in]: input_str   -> input string
    433      * @params[in]: token       -> character on which to split
    434      * @params[in]: max_splits  -> maximum number of splits. If negative will split from end of string
    435      * @return:     err             -> error code if there was a problem with csplitting.
    436      */
    437     _CSPLIT_FUNC
    438 
    439         CSplitError_t csplit_rstr(CSplitList_t* list, char* input_str, char* token, int max_splits) {
    440         CSplitError_t err = CSPLIT_SUCCESS;
    441         //unsigned     int in_len = 1;
    442         int    in_len = strlen(input_str) > 0 ? strlen(input_str) : 1;
    443         int counter = 0;
    444         int num_splits = 0;
    445         int token_len = strlen(token);
    446         char* current_location = input_str;
    447         char* arr = malloc(in_len);  ///char* arr[in_len];   Vs编译器 会报错
    448         while ((arr[counter] = strstr(current_location, token)) != NULL) {
    449             current_location = arr[counter] + 1;
    450             counter++;
    451         }
    452         char* last_location = input_str + in_len;
    453         while (counter >= 0 && num_splits >= max_splits) {
    454             current_location = arr[counter - 1] + token_len;
    455             CSplitFragment_t* fragment = (CSplitFragment_t*)calloc(1, sizeof(CSplitFragment_t));
    456             int req_buff_size;
    457             if (num_splits == max_splits || counter == 0) {
    458                 req_buff_size = in_len - strlen(last_location);
    459                 current_location = input_str;
    460             }
    461             else
    462                 req_buff_size = last_location - current_location;
    463             err = csplit_push_to_list(list, fragment, req_buff_size);
    464             strncpy(fragment->text, current_location, req_buff_size);
    465             last_location = current_location - token_len;
    466             num_splits--;
    467             counter--;
    468         }
    469         err = csplit_reverse_list(list);
    470         free(arr);
    471         return err;
    472     }
    473 
    474 
    475     /**
    476      * @brief Function that splits a given input string based on another string.
    477      * @ingroup intern
    478      *
    479      * @params[out]: list           -> output list splitting input str on string token
    480      * @params[in]: input_str       -> input string which will be split
    481      * @params[in]: token           -> string on which to split
    482      * @params[in]: max_splits      -> max number of splits to perform. Negative if starting from end of string.
    483      * @return:     err             -> error code if there was a problem with csplitting.
    484      */
    485     _CSPLIT_FUNC
    486         CSplitError_t csplit_str(CSplitList_t* list, char* input_str, char* token, int max_splits) {
    487         if (max_splits < 0)
    488             return 0;//csplit_rstr(list, input_str, token, max_splits);
    489         CSplitError_t err = CSPLIT_SUCCESS;
    490         int in_len = strlen(input_str);
    491         int num_splits = 0;
    492         int token_len = strlen(token);
    493         char* current_location = input_str;
    494         char* next_location;
    495 
    496         while (current_location != NULL && num_splits <= max_splits) {
    497             CSplitFragment_t* fragment = (CSplitFragment_t*)calloc(1, sizeof(CSplitFragment_t));
    498             next_location = strstr(current_location, token);
    499             int req_buff_size;
    500             if (next_location == NULL || (num_splits == max_splits))
    501                 req_buff_size = in_len - (current_location - input_str);
    502             else if (next_location != NULL)
    503                 req_buff_size = next_location - current_location;
    504             err = csplit_push_to_list(list, fragment, req_buff_size);
    505             strncpy(fragment->text, current_location, req_buff_size);
    506             if (next_location != NULL)
    507                 current_location = next_location + token_len;
    508             else {
    509 
    510                 current_location = next_location;
    511             }
    512             num_splits++;
    513         }
    514         return err;
    515     }
    516 
    517 
    518 
    519     /**
    520      * @brief Function that allows user to split based on a limited number of splits, either forward
    521      * or in reverse. A max_splits >= len(input_str) will guarantee all possible splits
    522      * @ingroup core
    523      *
    524      * @params[out]: list           -> output list splitting input str on string token
    525      * @params[in]: input_str       -> input string which will be split
    526      * @params[in]: token           -> string on which to split
    527      * @params[in]: max_splits      -> max number of splits to perform. Negative if starting from end of string.
    528      * @return:     err             -> error code if there was a problem with csplitting.
    529      */
    530     _CSPLIT_FUNC
    531         CSplitError_t csplit_lim(CSplitList_t* list, char* input_str, char* token, int max_splits) {
    532         CSplitError_t err = CSPLIT_SUCCESS;
    533         // first check to see if input string is valid and token is valid
    534         if (strlen(input_str) < 1 || strlen(token) < 1) {
    535             err = CSPLIT_TOO_SHORT;
    536         }
    537         else {
    538             // otherwise we split on the given string
    539             err = csplit_str(list, input_str, token, max_splits);
    540         }
    541         return err;
    542     }
    543 
    544 
    545     /**
    546      * @brief Top level csplit function call. Outputs a csplit list split on a string token. Calls
    547      * csplit_lim with max_splits = len(input_str), ensuring that all possible splits will be made.
    548      * @ingroup core
    549      *
    550      * @params[out]: list           -> output list splitting input str on string token
    551      * @params[in]: input_str       -> input string which will be split
    552      * @params[in]: token           -> string on which to split
    553      * @return:     err             -> error code if there was a problem with csplitting.
    554      */
    555     _CSPLIT_FUNC
    556         CSplitError_t csplit(CSplitList_t* list, char* input_str, char* token) {
    557         return csplit_lim(list, input_str, token, (int)strlen(input_str));
    558     }
    559 
    560 
    561     /**
    562      * @brief Function that runs csplit and then reverses the output.
    563      * @ingroup core
    564      *
    565      * @params[out]: output_list    -> output list splitting input str on string token
    566      * @params[in]: input_str       -> input string which will be split
    567      * @params[in]: token           -> string on which to split
    568      * @return:     err             -> error code if there was a problem with csplitting.
    569      */
    570     _CSPLIT_FUNC
    571         CSplitError_t rcsplit(CSplitList_t* output_list, char* input_str, char* token) {
    572         CSplitError_t err = csplit(output_list, input_str, token);
    573         if (err != CSPLIT_SUCCESS)
    574             return err;
    575         err = csplit_reverse_list(output_list);
    576         return err;
    577     }
    578 
    579 #ifdef __cplusplus
    580 }
    581 #endif
    582 
    583 #endif
    View Code

    main  可以正常运行

      1 #include <stdio.h>
      2 #include <stdlib.h>
      3 #include "csplit.h"
      4 
      5 
      6 /* run this program using the console pauser or add your own getch, system("pause") or input loop */
      7 
      8 #define BUFFSIZE  4016*11*1    
      9 static char tab[] = "0123456789ABCDEF";
     10 
     11 
     12 
     13 void Change(char* bin, size_t size, char* asc)
     14 {
     15 
     16     unsigned char* src = (unsigned char*)bin;
     17     unsigned char* dst = (unsigned char*)asc;
     18     while (size-- > 0)
     19     {
     20         *dst++ = tab[*src >> 4];
     21         *dst++ = tab[*src & 0xF];
     22         ++src;
     23     }
     24 }
     25 
     26 
     27 
     28 
     29 
     30 
     31 
     32 int main(int argc, char* argv[]) {
     33     // our test string
     34     unsigned  char* test_string = "F5A60000C71DE12901000C0000000000110068001E005E0020008B008FFF0200100067001D005D0021008A0090FF0200100066001F005E0020008A008FFF0100100067001E005D001F0089008FFF0100100068001D005F001F0089008FFF0100100068001E005F0020008A008FFF0200110068001F005E0020008A0090FF0200110068001F005F001F008A008FFF0200110069001F005D001F008A008FFF0200110068001E005F002000890090FF0200100067001E005F0020008A008FFF02000F0067001D005E001F008A0090FF0100100068001E005E0020008A008FFF0200110068001E005E001F0089008EFF02000F0067001F005D00200089008FFF0100110067001E005F001F008A008EFF0200110067001F005E0020008B008FFF02001100680020005E0020008A0090FF0100110068001E005E001E008A0090FF0100100068001F005F0020008A008FFF0200100066001F005D001F0089008FFF0200100067001F005F00200089008FFF0000100067001E005F001F008A008FFF0100100067001E005E0020008A008FFF0200100067001E005E0020008A008FFF0200110069001F005E0021008A0090FF0200120067001E005F001F0088008FFF0100100068001F005D00200089008EFF0100100067001E005E001E0089008FFF0200100067001E005D00200089008FFF0200100068001E005F001F0089008EFF0100100067001E005E001F008A008DFF01001100690020005E002000890090FF0300110068001F005F0021008B0090FF0200100067001F005E00200089008FFF0200100068001F005E001F008A0090FF0200100067001F005E00200089008EFF0200100068001D005E00200089008FFF0100100067001E005D00200089008FFF0200100068001E005D0020008A008FFF0100100068001F0060001F008A0090FF0200110068001F005F0020008A008FFF0100120067001E005E002000890090FF02000F0068001F005E00200088008FFF0100100067001F005E0020008A008FFF0100100068001E005D00200089008FFF02000F0068001E005E001F008A008FFF02000F0067001F005F00200089008EFF0100100067001F005D00200089008FFF0200110068001F005F0021008B008FFF0100110068001F005E002000890090FF0200100068001F005D001F0089008EFF0200100068001E005E0020008A008FFF0100110066001F005D00200088008FFF0300100067001E005E0020008A008EFF0200110068001E005E002000890090FF0100110067001F005D00200089008FFF0200110068001F005E0020008A008FFF0200120068001F005F002100890090FF01000F0067001F005F0021008A008FFF0100100067001F005F0020008A008EFF0200100067001E005E001F0089008EFF0100110067001F005E0020008A0090FF0100110067001F005E00200089008FFF0100100067001E005D002100890090FF0200100067001D005E0020008A008FFF0200120068001F005F0021008A0091FF0200100068001E005D0021008A008FFF0100100067001E005D001F0089008FFF0100110067001E005E001F008B008FFF0200100067001D005E001F008A0090FF0200110068001F005D0020008A0091FF0100100068001E005D00200088008EFF0200100067001E005E0020008B0090FF0200100069001F005E002100890091FF0100120067001F005F002000890090FF0200110067001E005E00200089008FFF0200100068001D005E0021008A008FFF0200100067001E005E001F0089008EFF0100100068001E005E001F008B008FFF0100110068001E005E001F0089008FFF01001100670020005D0020008A008FFF02001100680020005E001F008A008FFF0100100069001E005E0021008A008FFF0200110068001F005D0020008A008EFF0200110067001F005E00200089008FFF0200110068001E005D00200089008FFF0100110067001E005D00200089008FFF0200110067001E005E001F008A008FFF0200100068001E005D0020008A008EFF0200100068001F005E0021008A008EFF0100100069001F005F0021008A008FFF0200100067001E005E00200089008FFF0100100067001C005E001F008A008EFF0100100067001E005D001F008A008EFF02000F0068001E005E001F008A0090FF0100110068001D005E001F008A008FFF0100100068001E005F0020008A008EFF0200110067001D005D0020008A0090FF0100100068001F005E0020008B0090FF0200110067001F005E0021008A008EFF0200100066001E005E0020008A008FFF0100100067001E005D0020008A008FFF0200110067001D005E001F0089008FFF02000F0068001F005D001F00890090FF0100100067001E005D001F0089008FFF0100100068001E005E00200089008FFF0200100067001F005E0020008A008FFF0100110067001E005D001F008A008FFF0200110067001E005E001F0089008FFF0100100066001E005D00200089008FFF0200100066001F005E001F00890090FF0200100067001E005E00200089008FFF0100120068001F005E00200089008FFF0200110067001D005E001F0089008FFF0200110069001E005E00200089008FFF0200100067001F005E0021008A0090FF0200110067001F005F0020008A008FFF0100100068001E005D0020008A008EFF0200110067001E005E001F008A008EFF0100110067001E005D0020008A008FFF0200110068001F005D001F008A008FFF01000F0067001D005E0020008A008EFF0200110068001E005F002000890090FF01000F0066001E005E001F008A008FFF0200110069001E005E0021008A0090FF02000F0068001F005D0020008A008FFF02000F0068001E005D0020008A0090FF0200100068001E005F001F008A008EFF02000F0068001E005E00200089008FFF0200100067001F005E00200089008FFF0200100068001F005E0020008A008EFF0200100068001E005D00200089008EFF0200120068001E005E0020008A008FFF0300110067001F005D00200089008EFF0200100067001F005D001F008A008EFF0200110068001D005E0020008A008FFF0200100067001F005E001F0088008FFF0100100067001F005E001F0089008DFF0200120068001E005F00200089008EFF0100110069001F005E0020008A008EFF0100110067001F005F0020008A0090FF0100100067001F005E0020008A0091FF01001100680020005E0020008A008FFF0200100067001E005E0020008A008EFF0200100067001E005D00200089008FFF0200100067001D005F001F008A0090FF0200110067001F005E00200089008EFF0100110068001F005E001F0089008FFF0200110068001F005E0020008A008FFF0200110068001E005D001F008B0090FF0200110067001E005D001F008A008EFF0100100067001D005D0020008A008FFF0300110067001E005F00200089008EFF0200120068001E005E001F00890090FF0200100066001E005C00200089008EFF0300110067001E005D001F0089008FFF0300110068001F005D0020008A0090FF0100110068001E005E0021008A008FFF0200110067001F005D001F008A0090FF0200100066001D005E001F0089008FFF0200110066001F005E00200089008FFF0200100067001E005D002000890090FF0200100067001E005D0020008A0090FF0100100067001E005E0020008A008FFF0200100068001F005E002000890090FF0200110067001F005F0020008A0090FF0200120068001F005F0020008A008FFF0200110067001F005E0020008A0090FF01000F0067001E005E00200089008FFF0100100068001E005E001F008A008FFF0200100068001E005E001F008B0090FF0200110067001E005D001F0089008FFF0200110067001E005E00200088008FFF0300110067001F005E001F008A008FFF0200110068001D005F0021008A008FFF01001100680020005E00200089008EFF0200100068001F005E00200089008FFF0100100067001E005F00200089008EFF0200110068001E005D001F0089008FFF0200100068001F005E0020008A008FFF0200110067001D005F001E008B008FFF0100110069001F005D00200089008FFF0100110068001E005F0020008B0090FF0200110068001E005F001F0088008FFF01000F0067001E005D001F008A008EFF0100100067001E005E001F0089008FFF0200110067001F005D0020008A008FFF0200120067001E005E001F0089008FFF0100110067001E005F001F0089008EFF0200100068001F005E002000890090FF0200100068001F005E00200089008FFF0100110067001F005E0021008A008FFF0200120068001E005E00200089008EFF0200110067001F005E001F0089008FFF0200100068001D005D00200088008FFF0200110068001E005E00200089008EFF0100100068001E005E00220089008FFF0300110067001F005E00200089008FFF01000F0068001F005E002000890090FF0200110068001F005F0021008A008EFF0100100068001E005E0020008B0090FF02000F0067001E005E002000890091FF0200110068001F005E001F0089008FFF02000F0068001F005D001E0089008FFF0100100067001E005E001F008A0090FF0100110068001E005E002000890091FF0200110067001E005D00200089008FFF0200100068001F005E0020008B008FFF0200110066001E005E00200089008FFF0100110066001E005E0020008B008EFF01000F0068001E005E0020008A008FFF0200110068001D005D001F0089008FFF0100100067001E005D001F008A0090FF0100110067001E005D002000890090FF0200110068001F005E0020008A008FFF0200110068001E005E0020008A008FFF0200120067001D005E0020008A008FFF0100110068001E005E00200089008FFF0100110067001E005F00200088008FFF0200100068001E005F0021008A008FFF0200100067001E005E001F008A008FFF0200100068001F005F00200089008FFF01001000670020005D001F0089008FFF02001200680020005E0020008A008FFF02001100680020005D0020008A008FFF0200110067001F005F001F008A008FFF0100110067001F005D001F008A008EFF0100100068001F005E0020008A008FFF0100110067001E005E0020008B008EFF0200110067001F005D001F008A008FFF0100110067001F005E001F008A008EFF02000F0067001E005E0020008A008FFF0100110068001E005F0020008A008FFF0200110068001E005E00210089008FFF0200100068001E005E001F0089008EFF0200110068001E005E0020008A008FFF0200100067001F005E0020008A0090FF0200120068001F005E001F0089008EFF0200100069001F005F001F0089008FFF0200100068001E005D00200089008FFF0100110067001F005F002000890090FF0200100067001E005E001F008B008FFF0200110068001D005E0020008A008EFF0200100066001E005E00200089008EFF0200100067001E005D001E008A008FFF0200100068001E005E0020008A008FFF0200100068001E005E00200089008FFF0200110068001E005E001F00890090FF0100100068001F005D002000890090FF0200";
     35     //  printf("Our demo string is: %s
    ", test_string);
     36 
     37 
     38     FILE* filestr = fopen("FS_2020_0925_1241_45_12.txt", "rb");
     39     //unsigned    char buff[BUFFSIZE];
     40  //   unsigned    char buff2[BUFFSIZE];
     41     char* buff = NULL;
     42     char* buff2 = NULL;
     43     buff = (char*)malloc(BUFFSIZE);
     44     buff2 = (char*)malloc(BUFFSIZE * 2);
     45     int count = 0;
     46     int errnor = 0;
     47 
     48     memset(buff, 0, BUFFSIZE);
     49     //char ptemp[BUFFSIZE];
     50     memset(buff2, 0, BUFFSIZE * 2);
     51     int a = 0;
     52     while (!feof(filestr)) {
     53         count = fread(buff, sizeof(char), BUFFSIZE, filestr);
     54         if (count > 0)
     55         {
     56             Change(buff, BUFFSIZE, buff2);
     57         }
     58     // initialize our output list.
     59     CSplitList_t* list = csplit_init_list();
     60     // split on the " " (space) character
     61     CSplitError_t err = csplit(list,(char *)buff2, "F5A6");
     62     if (list == NULL) return;
     63     CSplitFragment_t* current_fragment = list->head;
     64     while (current_fragment != NULL) {
     65         printf("--%s", current_fragment->text);
     66         //current_fragment->text>>32;
     67       //  printf( "--%s", current_fragment->text);
     68         current_fragment = current_fragment->next;
     69     }
     70     // free memory
     71     csplit_clear_list(list);
     72     }
     73 
     74 
     75 
     76 
     77 
     78     return 0;
     79     //// print the list of split fragments to stdout
     80     //csplit_print_list_info(list, stdout);
     81 
     82     //// print a separator
     83     //printf("----------------------------
    ");
     84 
     85     //// demo of getting fragment string at an index, 3 index will give us "you"
     86     //char* test_get_index = csplit_get_fragment_at_index(list, 3);
     87 
     88     //// demo of getting fragment string using reverse index, -1 will give us the last
     89     //// fragment, in this case "doing?"
     90     //char* test_get_r_index = csplit_get_fragment_at_index(list, -1);
     91 
     92     //// print results
     93     //printf("Get index: %s
    ", test_get_index);
     94     //printf("Get reverse index: %s
    ", test_get_r_index);
     95 
     96     //// free memory
     97     //csplit_clear_list(list);
     98 
     99 
    100 
    101     //
    102     //     char* test_string = "Hello how are you doing?
    
    ";
    103     //    printf("Our demo string is: --%s--
    ", test_string);
    104     //
    105     //    // strip outermost whitespace (2 newlines)
    106     //    char* stripped_str = csplit_strip(test_string);
    107     //    printf("The stripped string is --%s--
    ", stripped_str);
    108     //    printf("Note the disappeared newline characters.
    ");
    109     //
    110     //    // startswith command
    111     //    int temp = csplit_startswith(test_string, "Hello");
    112     //    if(temp == 0){
    113     //        printf("The input started with 'Hello'
    ");
    114     //    }
    115     //
    116     //    // endswith - will fail here because of newlines, but succeed on the stripped one.
    117     //    temp = csplit_endswith(test_string, "doing?");
    118     //    if(temp == 0){
    119     //        printf("The input string ended with 'doing?'
    ");
    120     //    }
    121     //    temp = csplit_endswith(stripped_str, "doing?");
    122     //    if(temp == 0){
    123     //        printf("After stripping away newlines, the string ends with 'doing?'
    ");
    124     //    }
    125     //
    126     //    // remove all whitespace and print
    127     //    char* no_whitespace = csplit_remove_whitespace(test_string);
    128     //    printf("The input string without any whitespace: --%s--
    ", no_whitespace);
    129     //
    130     //    // free memory.
    131     //    free(stripped_str);
    132     //    free(no_whitespace);
    133 
    134 
    135 
    136 
    137     printf("%s", "777");
    138     return 0;
    139 }
    View Code
    /********************************************************************************
     * MIT License
     * 
     * Copyright (c) 2019 Jakub Wlodek
     * 
     * Permission is hereby granted, free of charge, to any person obtaining a copy
     * of this software and associated documentation files (the "Software"), to deal
     * in the Software without restriction, including without limitation the rights
     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     * copies of the Software, and to permit persons to whom the Software is
     * furnished to do so, subject to the following conditions:
     * 
     * The above copyright notice and this permission notice shall be included in all
     * copies or substantial portions of the Software.
     * 
     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
     * SOFTWARE.
     *********************************************************************************/
    
    /**
     * @defgroup intern Internal
     * @brief Internal functions, not intended to be used by users
     * @defgroup set Setup
     * @brief Setup and Diagnostic functions used by csplit
     * @defgroup core csplit Core
     * @brief Core functions included in csplit
     */
    
    /**
     * A single-header C library for string manipulation and splitting.
     * 
     * Author: Jakub Wlodek
     * Created: 02-Aug-2019
     */
    
    
    // Include guard - avoid redefinition
    #ifndef CSPLIT_H
    #define CSPLIT_H
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    // some basic includes
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <ctype.h>
    
    #ifdef _MSC_VER
    # define _CSPLIT_FUNC static __inline
    #elif !defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L
    # define _CSPLIT_FUNC static __inline__
    #else
    # define _CSPLIT_FUNC static inline
    #endif
    
    /**
     * Enum type for error codes for csplit
     * @ingroup set
     */
    typedef enum CSPLIT_ERROR {
        CSPLIT_SUCCESS          = 0,     /**< No Error */
        CSPLIT_TOO_SHORT        = -1,    /**< Input string is too short */
        CSPLIT_NO_SUCH_INDEX    = -2,    /**< Index out of range */
        CSPLIT_UNIMPLEMENTED    = -3,    /**< Function unimplemented */
        CSPLIT_BUFF_EXCEEDED    = -4,    /**< Buffer size exceeded */
    } CSplitError_t;
    
    
    /**
     * Struct for an individual string fragment result from csplit
     * @ingroup intern
     */
    typedef struct CSPLIT_FRAGMENT {
        char* text;                         /**< Text of the fragment. */
        struct CSPLIT_FRAGMENT* next;       /**< Next fragment in the linked list */
        struct CSPLIT_FRAGMENT* prev;       /**< Previous fragment in the linked list */
    } CSplitFragment_t;
    
    
    /**
     * Struct that stores the csplit linked list. Can be used as an arbitrary linked list
     * for strings, but is intended for use with csplit strtok replacement functions
     * @ingroup core
     */
    typedef struct CSPLIT_LIST {
        int num_elems;              /**< Number of elements in the list */
        CSplitFragment_t* head;     /**< Head of the linked list (first element) */
        CSplitFragment_t* tail;     /**< Tail of the linked list (last element) */
    } CSplitList_t;
    
    
    /* Function Declarations */
    
    _CSPLIT_FUNC
    CSplitList_t* csplit_init_list();
    
    _CSPLIT_FUNC
    void csplit_clear_list(CSplitList_t* list);
    
    _CSPLIT_FUNC
    CSplitError_t csplit_push_to_list(CSplitList_t* list, CSplitFragment_t* fragment, size_t buff_size);
    
    _CSPLIT_FUNC
    void csplit_print_list_info(CSplitList_t* list, FILE* fp);
    
    #ifdef CSPLIT_DEBUG
    _CSPLIT_FUNC
    void print_csplit_fragment_info(CSplitFragment_t* fragment, FILE* fp);
    #endif
    
    _CSPLIT_FUNC
    char* csplit_get_fragment_at_index(CSplitList_t* list, int index);
    
    _CSPLIT_FUNC
    CSplitError_t csplit_reverse_list(CSplitList_t* list);
    
    _CSPLIT_FUNC
    char* csplit_strip(char* input_str);
    
    _CSPLIT_FUNC
    char* csplit_remove_whitespace(char* input_str);
    
    _CSPLIT_FUNC
    int csplit_startswith(char* input_str, char* starts_with);
    
    _CSPLIT_FUNC
    int csplit_endswith(char* input_str, char* ends_with);
    
    _CSPLIT_FUNC
    CSplitError_t csplit_rstr(CSplitList_t* list, char* input_str, char* token, int max_splits);
    
    _CSPLIT_FUNC
    CSplitError_t csplit_str(CSplitList_t* list, char* input_str, char* token, int max_splits);
    
    _CSPLIT_FUNC
    CSplitError_t csplit_lim(CSplitList_t* list, char* input_str, char* token, int max_splits);
    
    _CSPLIT_FUNC
    CSplitError_t csplit(CSplitList_t* list, char* input_str, char* token);
    
    _CSPLIT_FUNC
    CSplitError_t rcsplit(CSplitList_t* output_list, char* input_str, char* token);
    
    
    /* Function Definitions */
    
    
    /**
     * @brief Function for initializing a csplit list
     * @ingroup set
     * 
     * @params[in]: buff_size   -> user set buffer size. Make sure this is large enough for your largest fragment
     * @return: list            -> an allocated csplit list
     */
    _CSPLIT_FUNC
    CSplitList_t* csplit_init_list(){
        CSplitList_t* list = (CSplitList_t*) calloc(1, sizeof(CSplitList_t));
        list->num_elems = 0;
        return list;
    }
    
    
    /**
     * @brief Clears all memory for an allocated csplit list
     * @ingroup set
     * 
     * @params[in]: list    -> a previously allocated csplit list to be freed
     */
    _CSPLIT_FUNC
    void csplit_clear_list(CSplitList_t* list){
        CSplitFragment_t* current_fragment = list->head;
        while(current_fragment != NULL){
            CSplitFragment_t* temp = current_fragment->next;
            free(current_fragment->text);
            free(current_fragment);
            current_fragment = temp;
        }
        free(list);
    }
    
    
    /**
     * @brief Function that pushes a new CSplitFragment to the end of the list, and allocates memory for the text,
     * with size list->BUFF_SIZE
     * @ingroup intern
     * 
     * @params[out]: list       -> The list with fragment appended to the tail
     * @params[in]: fragment    -> fragment to append to the list. fragment->text will be allocated based on list->BUFF_SIZE
     */
    _CSPLIT_FUNC
    CSplitError_t csplit_push_to_list(CSplitList_t* list, CSplitFragment_t* fragment, size_t buff_size){
        // first make sure neither is null
        if(list == NULL || fragment == NULL){
            return CSPLIT_TOO_SHORT;
        }
        else{
            // then update the number of elements, and the pointers
            list->num_elems = list->num_elems + 1;
            if(list->head == NULL){
                list->head = fragment;
                list->tail = fragment;
            }
            else{
                list->tail->next = fragment;
                fragment->prev = list->tail;
                list->tail = fragment;
            }
            // allocate fragment text field
            fragment->text = (char*) calloc(1, buff_size);
        }
        return CSPLIT_SUCCESS;
    }
    
    
    /**
     * @brief Function that prints information about a csplit list
     * @ingroup set
     * 
     * @params[in]: list    -> list for which to print info
     * @params[in]: fp      -> file pointer to print into.
     */
    _CSPLIT_FUNC
    void csplit_print_list_info(CSplitList_t* list, FILE* fp){
        if(list == NULL || fp == NULL) return;
        fprintf(fp, "List contains %d elements
    ", list->num_elems);
        fprintf(fp, "Supports indexes -%d to %d.
    ", list->num_elems, list->num_elems -1);
        CSplitFragment_t* current_fragment = list->head;
        while(current_fragment != NULL){
            fprintf(fp, "--%s--
    ", current_fragment->text);
            current_fragment = current_fragment->next;
        }
    }
    
    
    #ifdef CSPLIT_DEBUG
    /**
     * @brief Function that prints information about a csplit fragment - intended for internal use only
     * @ingroup intern
     * 
     * @params[in]: fragment    -> fragment for which to print info
     * @params[in]: fp          -> file pointer to print into
     */
    _CSPLIT_FUNC
    void print_csplit_fragment_info(CSplitFragment_t* fragment, FILE* fp){
        if(fragment == NULL || fp == NULL) return;
        fprintf(fp, "Fragment has text %s
    ", fragment->text);
        if(fragment->next != NULL) fprintf(fp, "Fragment has next with text %s
    ", fragment->next->text);
        if(fragment->prev != NULL) fprintf(fp, "Fragment has prev with text %s
    ", fragment->prev->text);    
    }
    #endif
    
    
    /**
     * @brief Function that returns the string fragment at a certain index in the list
     * @ingroup core
     * 
     * @params[in]: list    -> list generated by csplit
     * @params[in]: index   -> index to search for (can be negative for getting at index from back of list)
     * @return: text        -> string at the given index or NULL if index out of range.
     */
    _CSPLIT_FUNC
    char* csplit_get_fragment_at_index(CSplitList_t* list, int index){
        // convert index into absolute index (if negative);
        int target_index;
        if(index < 0){
            target_index = index + list->num_elems;
        }
        else{
            target_index = index;
        }
        // if index is out of range return null
        if(list->num_elems <= target_index || target_index < 0){
            return NULL;
        }
        else{
            // iterate over list until index found
            int counter = 0;
            CSplitFragment_t* current_fragment = list->head;
            while(counter < target_index){
                current_fragment = current_fragment->next;
                counter++;
            }
            // return the text field
            return current_fragment->text;
        }
    }
    
    
    /**
     * @brief Function that reverses the list generated by csplit
     * @ingroup set
     * 
     * @params[out]: list   -> list to reverse
     * @return: err         -> error code if there is an error
     */
    _CSPLIT_FUNC
    CSplitError_t csplit_reverse_list(CSplitList_t* list){
        int i;
        // iterate over list and swap next and previous fields
        CSplitFragment_t* temp = list->head;
        for(i = 0; i < list->num_elems; i++){
            CSplitFragment_t* temp2 = temp->next;
            temp->next = temp->prev;
            temp->prev = temp2;
            temp = temp2;
        }
        // swap head and tail
        temp = list->head;
        list->head = list->tail;
        list->tail = temp;
        return CSPLIT_SUCCESS;
    }
    
    
    /**
     * @brief Function that strips a given string into an output string. Will remove whitespace character:
     * 
    , 
    , 	, space will be removed from the start and end of each string.
     * @ingroup core
     * 
     * @params[in]: input_str   -> the input string to strip
     * @return: output_str      -> the string with whitespace removed from the ends. Must be freed.
     */
    _CSPLIT_FUNC
    char* csplit_strip(char* input_str){
        char* output_str;
        // check if input is null
        if(input_str == NULL)
            output_str = NULL;
        else{
            int len = strlen(input_str);
            char* end = input_str + len - 1;
            char* start = input_str;
            while(isspace(*start)){
                if(*start == '' || start == end) return NULL;
                else start++;
            }
            while(isspace(*end))
                end--;
    
            size_t buff_size = end - start + 1;
            output_str = (char*) calloc(1, buff_size + 1);
            strncpy(output_str, start, buff_size);
        }
        return output_str;
    }
    
    
    /**
     * @breifFunction that removes all whitespace characters of a given string into an output string.
     * Note that resulting char* must be free'd after it is no longer used
     * @ingroup core
     * 
     * @params[in]: input_str   -> the input string to strip
     * @return: output_str      -> the string with whitespace removed.
     */
    _CSPLIT_FUNC
    char* csplit_remove_whitespace(char* input_str){
        char* output_str;
        if(input_str == NULL)
            output_str = NULL;
        else{
            int len = strlen(input_str);
            output_str = (char*) calloc(1, len);
            int counter = 0;
            int output_counter = 0;
            // read through but don't copy whitespace
            while(counter < len){
                if(!isspace(input_str[counter])){
                    output_str[output_counter] = input_str[counter];
                    output_counter++;
                }
                counter++;
            }
        }
        return output_str;
    }
    
    
    /**
     * @brief Function that checks if a given string starts with another given string.
     * @ingroup core
     * 
     * @params[in]: input_str       -> string to check against
     * @params[in]: starts_with     -> string to try to match with start of input string
     * @return:     int             -> -2 if input is invalid, -1 if doesn't start with given string, or 0 if it does
     */
    _CSPLIT_FUNC
    int csplit_startswith(char* input_str, char* starts_with){
        if(input_str == NULL || starts_with == NULL) return -2;
        else if(strstr(input_str, starts_with) == input_str) return 0;
        else return -1;
    }
    
    
    /**
     * @brief Function that checks if a given string ends with another given string.
     * @ingroup core
     * 
     * @params[in]: input_str       -> string to check against
     * @params[in]: ends_with       -> string to try to match with end of input string
     * @return:     int             -> -2 if input is invalid, -1 if doesn't end with given string, or 0 if it does
     */
    _CSPLIT_FUNC
    int csplit_endswith(char* input_str, char* ends_with){
        if(input_str == NULL || ends_with == NULL){
            return -2;
        }
        else{
            int ewith_len = strlen(ends_with);
            int istr_len = strlen(input_str);
            if(ewith_len > istr_len) return -1;
            else if(strcmp(input_str + istr_len - ewith_len, ends_with) == 0) return 0;
            else return -1;
        }
    }
    
    
    /**
     * @brief Function that runs csplit on a particular string from the end of the input. Called if max_splits < 0
     * @ingroup intern
     * 
     * @params[out]: list       -> split input string into this list structure
     * @params[in]: input_str   -> input string
     * @params[in]: token       -> character on which to split
     * @params[in]: max_splits  -> maximum number of splits. If negative will split from end of string
     * @return:     err             -> error code if there was a problem with csplitting.
     */
    _CSPLIT_FUNC
    CSplitError_t csplit_rstr(CSplitList_t* list, char* input_str, char* token, int max_splits){
        CSplitError_t err = CSPLIT_SUCCESS;
        int in_len = strlen(input_str);
        int counter = 0;
        int num_splits = 0;
        int token_len = strlen(token);
        char* current_location = input_str;
        char* arr[in_len];
        while((arr[counter] = strstr(current_location, token)) != NULL){
            current_location = arr[counter] + 1;
            counter++;
        }
        char* last_location = input_str + in_len;
        while(counter >= 0 && num_splits >= max_splits){
            current_location = arr[counter - 1] + token_len;
            CSplitFragment_t* fragment = (CSplitFragment_t*) calloc(1, sizeof(CSplitFragment_t));
            size_t req_buff_size;
            if(num_splits == max_splits || counter == 0){
                req_buff_size = in_len - strlen(last_location);
                current_location = input_str;
            }
            else
                req_buff_size = last_location - current_location;
            err = csplit_push_to_list(list, fragment, req_buff_size);
            strncpy(fragment->text, current_location, req_buff_size);
            last_location = current_location - token_len;
            num_splits--;
            counter--;
        }
        err = csplit_reverse_list(list);
        return err;
    }
    
    
    /**
     * @brief Function that splits a given input string based on another string.
     * @ingroup intern
     * 
     * @params[out]: list           -> output list splitting input str on string token
     * @params[in]: input_str       -> input string which will be split
     * @params[in]: token           -> string on which to split
     * @params[in]: max_splits      -> max number of splits to perform. Negative if starting from end of string.
     * @return:     err             -> error code if there was a problem with csplitting.
     */
    _CSPLIT_FUNC
    CSplitError_t csplit_str(CSplitList_t* list, char* input_str, char* token, int max_splits){
        if(max_splits < 0)
            return csplit_rstr(list, input_str, token, max_splits);
        CSplitError_t err = CSPLIT_SUCCESS;
        int in_len = strlen(input_str);
        int num_splits = 0;
        int token_len = strlen(token);
        char* current_location = input_str;
        char* next_location;
    
        while(current_location != NULL && num_splits <= max_splits){
            CSplitFragment_t* fragment = (CSplitFragment_t*) calloc(1, sizeof(CSplitFragment_t));
            next_location = strstr(current_location, token);
            size_t req_buff_size;
            if(next_location == NULL || (num_splits == max_splits))
                req_buff_size = in_len - (current_location - input_str);
            else if(next_location != NULL)
                req_buff_size = next_location - current_location;
            err = csplit_push_to_list(list, fragment, req_buff_size);
            strncpy(fragment->text, current_location, req_buff_size);
            if(next_location != NULL)
                current_location = next_location + token_len;
            else{
    
                current_location = next_location;
            }
            num_splits++;
        }
        return err;
    }
    
    
    
    /**
     * @brief Function that allows user to split based on a limited number of splits, either forward
     * or in reverse. A max_splits >= len(input_str) will guarantee all possible splits
     * @ingroup core
     * 
     * @params[out]: list           -> output list splitting input str on string token
     * @params[in]: input_str       -> input string which will be split
     * @params[in]: token           -> string on which to split
     * @params[in]: max_splits      -> max number of splits to perform. Negative if starting from end of string.
     * @return:     err             -> error code if there was a problem with csplitting.
     */
    _CSPLIT_FUNC
    CSplitError_t csplit_lim(CSplitList_t* list, char* input_str, char* token, int max_splits){
        CSplitError_t err = CSPLIT_SUCCESS;
        // first check to see if input string is valid and token is valid
        if(strlen(input_str) < 1 || strlen(token) < 1){
            err = CSPLIT_TOO_SHORT;
        }
        else{
            // otherwise we split on the given string
            err = csplit_str(list, input_str, token, max_splits);
        }
        return err;
    }
    
    
    /**
     * @brief Top level csplit function call. Outputs a csplit list split on a string token. Calls
     * csplit_lim with max_splits = len(input_str), ensuring that all possible splits will be made.
     * @ingroup core
     * 
     * @params[out]: list           -> output list splitting input str on string token
     * @params[in]: input_str       -> input string which will be split
     * @params[in]: token           -> string on which to split 
     * @return:     err             -> error code if there was a problem with csplitting.
     */
    _CSPLIT_FUNC
    CSplitError_t csplit(CSplitList_t* list, char* input_str, char* token){
        return csplit_lim(list, input_str, token, (int) strlen(input_str));
    }
    
    
    /**
     * @brief Function that runs csplit and then reverses the output.
     * @ingroup core
     * 
     * @params[out]: output_list    -> output list splitting input str on string token
     * @params[in]: input_str       -> input string which will be split
     * @params[in]: token           -> string on which to split 
     * @return:     err             -> error code if there was a problem with csplitting.
     */
    _CSPLIT_FUNC
    CSplitError_t rcsplit(CSplitList_t* output_list, char* input_str, char* token){
        CSplitError_t err = csplit(output_list, input_str, token);
        if(err != CSPLIT_SUCCESS)
            return err;
        err = csplit_reverse_list(output_list);
        return err;
    }
    
    #ifdef __cplusplus
    }
    #endif
    
    #endif
    #include <stdio.h>
    #include <stdlib.h>
    #include "csplit.h"
    
    /* run this program using the console pauser or add your own getch, system("pause") or input loop */
    
    int main(int argc, char *argv[]) {
        // our test string
        char* test_string = "F5A60000C71DE12901000C0000000000110068001E005E0020008B008FFF0200100067001D005D0021008A0090FF0200100066001F005E0020008A008FFF0100100067001E005D001F0089008FFF0100100068001D005F001F0089008FFF0100100068001E005F0020008A008FFF0200110068001F005E0020008A0090FF0200110068001F005F001F008A008FFF0200110069001F005D001F008A008FFF0200110068001E005F002000890090FF0200100067001E005F0020008A008FFF02000F0067001D005E001F008A0090FF0100100068001E005E0020008A008FFF0200110068001E005E001F0089008EFF02000F0067001F005D00200089008FFF0100110067001E005F001F008A008EFF0200110067001F005E0020008B008FFF02001100680020005E0020008A0090FF0100110068001E005E001E008A0090FF0100100068001F005F0020008A008FFF0200100066001F005D001F0089008FFF0200100067001F005F00200089008FFF0000100067001E005F001F008A008FFF0100100067001E005E0020008A008FFF0200100067001E005E0020008A008FFF0200110069001F005E0021008A0090FF0200120067001E005F001F0088008FFF0100100068001F005D00200089008EFF0100100067001E005E001E0089008FFF0200100067001E005D00200089008FFF0200100068001E005F001F0089008EFF0100100067001E005E001F008A008DFF01001100690020005E002000890090FF0300110068001F005F0021008B0090FF0200100067001F005E00200089008FFF0200100068001F005E001F008A0090FF0200100067001F005E00200089008EFF0200100068001D005E00200089008FFF0100100067001E005D00200089008FFF0200100068001E005D0020008A008FFF0100100068001F0060001F008A0090FF0200110068001F005F0020008A008FFF0100120067001E005E002000890090FF02000F0068001F005E00200088008FFF0100100067001F005E0020008A008FFF0100100068001E005D00200089008FFF02000F0068001E005E001F008A008FFF02000F0067001F005F00200089008EFF0100100067001F005D00200089008FFF0200110068001F005F0021008B008FFF0100110068001F005E002000890090FF0200100068001F005D001F0089008EFF0200100068001E005E0020008A008FFF0100110066001F005D00200088008FFF0300100067001E005E0020008A008EFF0200110068001E005E002000890090FF0100110067001F005D00200089008FFF0200110068001F005E0020008A008FFF0200120068001F005F002100890090FF01000F0067001F005F0021008A008FFF0100100067001F005F0020008A008EFF0200100067001E005E001F0089008EFF0100110067001F005E0020008A0090FF0100110067001F005E00200089008FFF0100100067001E005D002100890090FF0200100067001D005E0020008A008FFF0200120068001F005F0021008A0091FF0200100068001E005D0021008A008FFF0100100067001E005D001F0089008FFF0100110067001E005E001F008B008FFF0200100067001D005E001F008A0090FF0200110068001F005D0020008A0091FF0100100068001E005D00200088008EFF0200100067001E005E0020008B0090FF0200100069001F005E002100890091FF0100120067001F005F002000890090FF0200110067001E005E00200089008FFF0200100068001D005E0021008A008FFF0200100067001E005E001F0089008EFF0100100068001E005E001F008B008FFF0100110068001E005E001F0089008FFF01001100670020005D0020008A008FFF02001100680020005E001F008A008FFF0100100069001E005E0021008A008FFF0200110068001F005D0020008A008EFF0200110067001F005E00200089008FFF0200110068001E005D00200089008FFF0100110067001E005D00200089008FFF0200110067001E005E001F008A008FFF0200100068001E005D0020008A008EFF0200100068001F005E0021008A008EFF0100100069001F005F0021008A008FFF0200100067001E005E00200089008FFF0100100067001C005E001F008A008EFF0100100067001E005D001F008A008EFF02000F0068001E005E001F008A0090FF0100110068001D005E001F008A008FFF0100100068001E005F0020008A008EFF0200110067001D005D0020008A0090FF0100100068001F005E0020008B0090FF0200110067001F005E0021008A008EFF0200100066001E005E0020008A008FFF0100100067001E005D0020008A008FFF0200110067001D005E001F0089008FFF02000F0068001F005D001F00890090FF0100100067001E005D001F0089008FFF0100100068001E005E00200089008FFF0200100067001F005E0020008A008FFF0100110067001E005D001F008A008FFF0200110067001E005E001F0089008FFF0100100066001E005D00200089008FFF0200100066001F005E001F00890090FF0200100067001E005E00200089008FFF0100120068001F005E00200089008FFF0200110067001D005E001F0089008FFF0200110069001E005E00200089008FFF0200100067001F005E0021008A0090FF0200110067001F005F0020008A008FFF0100100068001E005D0020008A008EFF0200110067001E005E001F008A008EFF0100110067001E005D0020008A008FFF0200110068001F005D001F008A008FFF01000F0067001D005E0020008A008EFF0200110068001E005F002000890090FF01000F0066001E005E001F008A008FFF0200110069001E005E0021008A0090FF02000F0068001F005D0020008A008FFF02000F0068001E005D0020008A0090FF0200100068001E005F001F008A008EFF02000F0068001E005E00200089008FFF0200100067001F005E00200089008FFF0200100068001F005E0020008A008EFF0200100068001E005D00200089008EFF0200120068001E005E0020008A008FFF0300110067001F005D00200089008EFF0200100067001F005D001F008A008EFF0200110068001D005E0020008A008FFF0200100067001F005E001F0088008FFF0100100067001F005E001F0089008DFF0200120068001E005F00200089008EFF0100110069001F005E0020008A008EFF0100110067001F005F0020008A0090FF0100100067001F005E0020008A0091FF01001100680020005E0020008A008FFF0200100067001E005E0020008A008EFF0200100067001E005D00200089008FFF0200100067001D005F001F008A0090FF0200110067001F005E00200089008EFF0100110068001F005E001F0089008FFF0200110068001F005E0020008A008FFF0200110068001E005D001F008B0090FF0200110067001E005D001F008A008EFF0100100067001D005D0020008A008FFF0300110067001E005F00200089008EFF0200120068001E005E001F00890090FF0200100066001E005C00200089008EFF0300110067001E005D001F0089008FFF0300110068001F005D0020008A0090FF0100110068001E005E0021008A008FFF0200110067001F005D001F008A0090FF0200100066001D005E001F0089008FFF0200110066001F005E00200089008FFF0200100067001E005D002000890090FF0200100067001E005D0020008A0090FF0100100067001E005E0020008A008FFF0200100068001F005E002000890090FF0200110067001F005F0020008A0090FF0200120068001F005F0020008A008FFF0200110067001F005E0020008A0090FF01000F0067001E005E00200089008FFF0100100068001E005E001F008A008FFF0200100068001E005E001F008B0090FF0200110067001E005D001F0089008FFF0200110067001E005E00200088008FFF0300110067001F005E001F008A008FFF0200110068001D005F0021008A008FFF01001100680020005E00200089008EFF0200100068001F005E00200089008FFF0100100067001E005F00200089008EFF0200110068001E005D001F0089008FFF0200100068001F005E0020008A008FFF0200110067001D005F001E008B008FFF0100110069001F005D00200089008FFF0100110068001E005F0020008B0090FF0200110068001E005F001F0088008FFF01000F0067001E005D001F008A008EFF0100100067001E005E001F0089008FFF0200110067001F005D0020008A008FFF0200120067001E005E001F0089008FFF0100110067001E005F001F0089008EFF0200100068001F005E002000890090FF0200100068001F005E00200089008FFF0100110067001F005E0021008A008FFF0200120068001E005E00200089008EFF0200110067001F005E001F0089008FFF0200100068001D005D00200088008FFF0200110068001E005E00200089008EFF0100100068001E005E00220089008FFF0300110067001F005E00200089008FFF01000F0068001F005E002000890090FF0200110068001F005F0021008A008EFF0100100068001E005E0020008B0090FF02000F0067001E005E002000890091FF0200110068001F005E001F0089008FFF02000F0068001F005D001E0089008FFF0100100067001E005E001F008A0090FF0100110068001E005E002000890091FF0200110067001E005D00200089008FFF0200100068001F005E0020008B008FFF0200110066001E005E00200089008FFF0100110066001E005E0020008B008EFF01000F0068001E005E0020008A008FFF0200110068001D005D001F0089008FFF0100100067001E005D001F008A0090FF0100110067001E005D002000890090FF0200110068001F005E0020008A008FFF0200110068001E005E0020008A008FFF0200120067001D005E0020008A008FFF0100110068001E005E00200089008FFF0100110067001E005F00200088008FFF0200100068001E005F0021008A008FFF0200100067001E005E001F008A008FFF0200100068001F005F00200089008FFF01001000670020005D001F0089008FFF02001200680020005E0020008A008FFF02001100680020005D0020008A008FFF0200110067001F005F001F008A008FFF0100110067001F005D001F008A008EFF0100100068001F005E0020008A008FFF0100110067001E005E0020008B008EFF0200110067001F005D001F008A008FFF0100110067001F005E001F008A008EFF02000F0067001E005E0020008A008FFF0100110068001E005F0020008A008FFF0200110068001E005E00210089008FFF0200100068001E005E001F0089008EFF0200110068001E005E0020008A008FFF0200100067001F005E0020008A0090FF0200120068001F005E001F0089008EFF0200100069001F005F001F0089008FFF0200100068001E005D00200089008FFF0100110067001F005F002000890090FF0200100067001E005E001F008B008FFF0200110068001D005E0020008A008EFF0200100066001E005E00200089008EFF0200100067001E005D001E008A008FFF0200100068001E005E0020008A008FFF0200100068001E005E00200089008FFF0200110068001E005E001F00890090FF0100100068001F005D002000890090FF0200";
        //  printf("Our demo string is: %s
    ", test_string);
    
        // initialize our output list.
        CSplitList_t* list = csplit_init_list();
    
        // split on the " " (space) character
        CSplitError_t err = csplit(list, test_string, "F5A6");
    
    
        if(list == NULL ) return;
       
        CSplitFragment_t* current_fragment = list->head;
        while(current_fragment != NULL){
            printf( "--%s", current_fragment->text);
             //current_fragment->text>>32;
           //  printf( "--%s", current_fragment->text);
            current_fragment = current_fragment->next;
        }
    
    
    
    return 0;
        // print the list of split fragments to stdout
        csplit_print_list_info(list, stdout);
    
        // print a separator
        printf("----------------------------
    ");
    
        // demo of getting fragment string at an index, 3 index will give us "you"
        char* test_get_index = csplit_get_fragment_at_index(list, 3);
    
        // demo of getting fragment string using reverse index, -1 will give us the last
        // fragment, in this case "doing?"
        char* test_get_r_index = csplit_get_fragment_at_index(list, -1);
    
        // print results
        printf("Get index: %s
    ", test_get_index);
        printf("Get reverse index: %s
    ", test_get_r_index);
    
        // free memory
        csplit_clear_list(list);
    
    
    
    //
    //     char* test_string = "Hello how are you doing?
    
    ";
    //    printf("Our demo string is: --%s--
    ", test_string);
    //
    //    // strip outermost whitespace (2 newlines)
    //    char* stripped_str = csplit_strip(test_string);
    //    printf("The stripped string is --%s--
    ", stripped_str);
    //    printf("Note the disappeared newline characters.
    ");
    //
    //    // startswith command
    //    int temp = csplit_startswith(test_string, "Hello");
    //    if(temp == 0){
    //        printf("The input started with 'Hello'
    ");
    //    }
    //
    //    // endswith - will fail here because of newlines, but succeed on the stripped one.
    //    temp = csplit_endswith(test_string, "doing?");
    //    if(temp == 0){
    //        printf("The input string ended with 'doing?'
    ");
    //    }
    //    temp = csplit_endswith(stripped_str, "doing?");
    //    if(temp == 0){
    //        printf("After stripping away newlines, the string ends with 'doing?'
    ");
    //    }
    //
    //    // remove all whitespace and print
    //    char* no_whitespace = csplit_remove_whitespace(test_string);
    //    printf("The input string without any whitespace: --%s--
    ", no_whitespace);
    //
    //    // free memory.
    //    free(stripped_str);
    //    free(no_whitespace);
    
    
    
    
        printf("%s","777");
        return 0;
    }
  • 相关阅读:
    003.iSCSI客户端管理
    002.iSCSI服务端配置
    001.iSCSI简介
    004.RAID删除
    003.RAID管理
    002.RAID创建
    001.RAID简介
    001.hadoop及hbase部署
    001.Parted工具使用
    007.LVM查看命令
  • 原文地址:https://www.cnblogs.com/mrguoguo/p/13744900.html
Copyright © 2020-2023  润新知