纯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\n", list->num_elems);
235         fprintf(fp, "Supports indexes -%d to %d.\n", list->num_elems, list->num_elems - 1);
236         CSplitFragment_t* current_fragment = list->head;
237         while (current_fragment != NULL) {
238             fprintf(fp, "--%s--\n", 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\n", fragment->text);
256         if (fragment->next != NULL) fprintf(fp, "Fragment has next with text %s\n", fragment->next->text);
257         if (fragment->prev != NULL) fprintf(fp, "Fragment has prev with text %s\n", 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      * \n, \r, \t, 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 == '\0' || 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\n", 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("----------------------------\n");
 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\n", test_get_index);
 94     //printf("Get reverse index: %s\n", 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?\n\n";
103     //    printf("Our demo string is: --%s--\n", test_string);
104     //
105     //    // strip outermost whitespace (2 newlines)
106     //    char* stripped_str = csplit_strip(test_string);
107     //    printf("The stripped string is --%s--\n", stripped_str);
108     //    printf("Note the disappeared newline characters.\n");
109     //
110     //    // startswith command
111     //    int temp = csplit_startswith(test_string, "Hello");
112     //    if(temp == 0){
113     //        printf("The input started with 'Hello'\n");
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?'\n");
120     //    }
121     //    temp = csplit_endswith(stripped_str, "doing?");
122     //    if(temp == 0){
123     //        printf("After stripping away newlines, the string ends with 'doing?'\n");
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--\n", 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\n", list->num_elems);
    fprintf(fp, "Supports indexes -%d to %d.\n", list->num_elems, list->num_elems -1);
    CSplitFragment_t* current_fragment = list->head;
    while(current_fragment != NULL){
        fprintf(fp, "--%s--\n", 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\n", fragment->text);
    if(fragment->next != NULL) fprintf(fp, "Fragment has next with text %s\n", fragment->next->text);
    if(fragment->prev != NULL) fprintf(fp, "Fragment has prev with text %s\n", 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:
 * \n, \r, \t, 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 == '\0' || 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\n", 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("----------------------------\n");

    // 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\n", test_get_index);
    printf("Get reverse index: %s\n", test_get_r_index);

    // free memory
    csplit_clear_list(list);



//
//     char* test_string = "Hello how are you doing?\n\n";
//    printf("Our demo string is: --%s--\n", test_string);
//
//    // strip outermost whitespace (2 newlines)
//    char* stripped_str = csplit_strip(test_string);
//    printf("The stripped string is --%s--\n", stripped_str);
//    printf("Note the disappeared newline characters.\n");
//
//    // startswith command
//    int temp = csplit_startswith(test_string, "Hello");
//    if(temp == 0){
//        printf("The input started with 'Hello'\n");
//    }
//
//    // 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?'\n");
//    }
//    temp = csplit_endswith(stripped_str, "doing?");
//    if(temp == 0){
//        printf("After stripping away newlines, the string ends with 'doing?'\n");
//    }
//
//    // remove all whitespace and print
//    char* no_whitespace = csplit_remove_whitespace(test_string);
//    printf("The input string without any whitespace: --%s--\n", no_whitespace);
//
//    // free memory.
//    free(stripped_str);
//    free(no_whitespace);




    printf("%s","777");
    return 0;
}

 

posted @ 2020-09-28 15:21  一颗大白鲸  阅读(243)  评论(0编辑  收藏  举报