fork download
  1. #include <stdlib.h>
  2. #include <string.h>
  3. #include <stdio.h>
  4. #include <ctype.h>
  5.  
  6.  
  7.  
  8. // for MSVC
  9. #ifdef _WIN32
  10. #define snprintf sprintf_s
  11. #endif
  12.  
  13.  
  14.  
  15. int pack( char const * SrcStr, char * DstBuf, size_t DstBuf_Size ) {
  16.  
  17. int Err = 0;
  18.  
  19. char const * Src_Ptr = SrcStr;
  20. char * Dst_Ptr = DstBuf;
  21.  
  22. size_t SrcBuf_Size = strlen( SrcStr ) + 1;
  23. char const * SrcBuf_End = SrcStr + SrcBuf_Size;
  24. char const * DstBuf_End = DstBuf + DstBuf_Size;
  25.  
  26. char c = 0;
  27. int RepeatCount = 1;
  28.  
  29. // don't forget about buffers intercrossing
  30. if( !SrcStr || !DstBuf || 0 == DstBuf_Size || (DstBuf < SrcBuf_End && DstBuf_End > SrcStr) ) {
  31. return 1;
  32. }
  33.  
  34. // source string must contain no digits
  35. // check for destination buffer overflow
  36. while( '\0' != *Src_Ptr && Dst_Ptr < DstBuf_End - 1 && !isdigit( *Src_Ptr ) && !Err ) {
  37.  
  38. c = *Dst_Ptr = *Src_Ptr;
  39. ++Src_Ptr; ++Dst_Ptr;
  40.  
  41. for( RepeatCount = 1; *Src_Ptr == c; ++RepeatCount ) {
  42. ++Src_Ptr;
  43. }
  44.  
  45. if( RepeatCount > 1 ) {
  46. int res = snprintf( Dst_Ptr, DstBuf_End - Dst_Ptr - 1, "%i", RepeatCount );
  47. if( res < 0 ) {
  48. Err = 1;
  49. } else {
  50. Dst_Ptr += res;
  51. RepeatCount = 1;
  52. }
  53. }
  54. }
  55.  
  56. *Dst_Ptr = '\0';
  57.  
  58. return Err;
  59. };
  60.  
  61. int unpack( char const * SrcStr, char * DstBuf, size_t DstBuf_Size ) {
  62.  
  63. int Err = 0;
  64.  
  65. char const * Src_Ptr = SrcStr;
  66. char * Dst_Ptr = DstBuf;
  67.  
  68. size_t SrcBuf_Size = strlen( SrcStr ) + 1;
  69. char const * SrcBuf_End = SrcStr + SrcBuf_Size;
  70. char const * DstBuf_End = DstBuf + DstBuf_Size;
  71.  
  72. char c = 0;
  73.  
  74. // don't forget about buffers intercrossing
  75. // first character of source string must be non-digit
  76. if( !SrcStr || !DstBuf || 0 == DstBuf_Size || (DstBuf < SrcBuf_End && DstBuf_End > SrcStr) \
  77. || isdigit( SrcStr[0] ) ) {
  78.  
  79. return 1;
  80. }
  81.  
  82. // check for destination buffer overflow
  83. while( '\0' != *Src_Ptr && Dst_Ptr < DstBuf_End - 1 && !Err ) {
  84.  
  85. if( !isdigit( *Src_Ptr ) ) {
  86. c = *Dst_Ptr = *Src_Ptr;
  87. ++Src_Ptr; ++Dst_Ptr;
  88.  
  89. } else {
  90. int repeat_count = strtol( Src_Ptr, (char**)&Src_Ptr, 10 );
  91. if( !repeat_count || repeat_count - 1 > DstBuf_End - Dst_Ptr - 1 ) {
  92. Err = 1;
  93. } else {
  94. memset( Dst_Ptr, c, repeat_count - 1 );
  95. Dst_Ptr += repeat_count - 1;
  96. }
  97. }
  98. }
  99.  
  100. *Dst_Ptr = '\0';
  101.  
  102. return Err;
  103. };
  104.  
  105. int main() {
  106.  
  107. char str[] = "aabbbccccddddd";
  108. char buf1[128] = {0};
  109. char buf2[128] = {0};
  110.  
  111. pack( str, buf1, 128 );
  112. printf( "pack: %s -> %s\n", str, buf1 );
  113.  
  114. unpack( buf1, buf2, 128 );
  115. printf( "unpack: %s -> %s\n", buf1, buf2 );
  116.  
  117. return 0;
  118. }
Success #stdin #stdout 0s 2292KB
stdin
Standard input is empty
stdout
pack: aabbbccccddddd -> a2b3c4d5
unpack: a2b3c4d5 -> aabbbccccddddd