1. C++ / Говнокод #26603

    +1

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    25. 25
    26. 26
    27. 27
    28. 28
    29. 29
    30. 30
    31. 31
    32. 32
    33. 33
    34. 34
    35. 35
    36. 36
    37. 37
    38. 38
    39. 39
    40. 40
    41. 41
    42. 42
    43. 43
    44. 44
    45. 45
    46. 46
    47. 47
    48. 48
    49. 49
    50. 50
    51. 51
    52. 52
    53. 53
    54. 54
    55. 55
    56. 56
    57. 57
    58. 58
    59. 59
    60. 60
    61. 61
    62. 62
    63. 63
    64. 64
    65. 65
    66. 66
    67. 67
    68. 68
    69. 69
    70. 70
    71. 71
    72. 72
    73. 73
    74. 74
    75. 75
    76. 76
    77. 77
    78. 78
    79. 79
    80. 80
    81. 81
    82. 82
    83. 83
    84. 84
    85. 85
    86. 86
    87. 87
    CStringUtf8::iterator& CStringUtf8::iterator::operator++() 
    { 
        m_ptr += CCharUtf8Ref::s_bytesForUTF8Sequence[*m_ptr]; 
        return *this;
    }
    
    CStringUtf8 CStringUtf8::subString( size_t startChar, size_t count ) const
    {
        iterator start = this->begin();
        while( start!=this->end() && startChar>0 )
        {
            start++;
            startChar--;
        }
    
        iterator afterLast = start;
        while( afterLast!=this->end() && count!=0 )
        {
            afterLast++;
            count--;
        }
        return CStringUtf8( start.c_ptr(), afterLast.c_ptr() );
    }
    
    CStringUtf8::iterator CStringUtf8::findSubString( CStringUtf8 const& sample, CStringUtf8::iterator startFrom ) const
    {
        CStringUtf8::iterator pos = startFrom;
        CStringUtf8::iterator foundPos = pos;
        CStringUtf8::iterator samplePos = sample.begin();
    
        for( ;; )
        {
            if( samplePos==sample.end() )
                return foundPos;
    
            if( pos==this->end() )
                return this->end();
    
            if( *samplePos == *pos )
            {
                if( samplePos==sample.begin() )
                    foundPos = pos;
                samplePos++;
                pos++;
            }
            else
            {
                if( samplePos==sample.begin() )
                    pos++;
                samplePos = sample.begin();
            }
        }
    }
    
    std::vector<CStringUtf8> CStringUtf8::componentsSeparatedByString( CStringUtf8 const& separator ) const
    {
        std::vector<CStringUtf8> comps;
    
        size_t sepLen = std::distance( separator.begin(), separator.end() );
        size_t startPos = 0;
        CStringUtf8::iterator itStart = begin();
    
        if( sepLen > 0 )
        {
            CStringUtf8::iterator itEnd;
            while( ( itEnd = findSubString( separator, itStart ) ) != end() )
            {
                size_t cnt = std::distance( itStart, itEnd );
                CStringUtf8 str = subString( startPos, cnt );
                comps.push_back( str );
    
                itStart = itEnd;
                std::advance( itStart, sepLen );
    
                startPos += cnt + sepLen;
            }
        }
    
        size_t cnt = std::distance( itStart, end() );
        if( cnt > 0 )
        {
            CStringUtf8 str = subString( startPos, cnt );
            comps.push_back( str );
        }
    
        return comps;
    }

    Привычный для всех плюсовиков велосипед по работе со строкой (походу свой в каждом проекте).
    Более 10 лет не замечали тормоза в componentsSeparatedByString, который 100 Кб текст разбирал на строки за 5-10 сек (!!!).

    Запостил: jojaxon, 26 Апреля 2020

    Комментарии (24) RSS

    • > тормоза

      Да пофиг на тормоза, функция findSubString() вообще не рабочая. Попробуй найти "aab" в "aaab", к примеру.
      Ответить
      • Похоже, отсутствие тестов тоже лет 10 не замечали.
        Ответить
        • Бля. Видимо не очень-то и нужен был поиск. Конец строки ищет и ладно.
          Тесты - это больная мозоль. Их мало, но они в тельняшках.
          Ответить
      • Протрнйсил в голове, вроде норм.

        Не могла же она просуществовать 10 лет некорректная?
        Ответить
        • Проверил. Реально не ищет
          Ответить
          • Чорт!

            У меня мозг протух.
            Ответить
            • Проапгрейдился до обезьяна. Проверяйте.

              Ща говном кидатся начну! Уук! Уук! Кууик!
              Ответить
    • Не понимаю, в языке же есть поддержка ООП, почему её не используют? Почему, например, получение размера строки нельзя прокешировать при изменении строки и затем брать из отдельного метода класса CStringUtf8, вроде length()?

      В чём логика передачи пустой строки как аргумента метода componentsSeparatedByString()? Куда разумнее здесь было бы бросить assert, нет? Если уж смысл в том, чтобы вернуть массив, содержащий единственный элемент, равный исходной строке (хотя, как мне кажется, логичнее при пустом аргументе было бы разбить всю строку по символам и вернуть массив этих символов), почему нельзя сделать отдельную проверку в самом начале с последующим простым возвратом из метода, вместо того чтобы считать размер строки и брать подстроку равную исходной строке?

      subString() делает что-то уж совсем сложное, почему просто не сделать clamp() по 0, размеру строки и стартовому индексу и передать первым параметром со сдвигом по внутреннему указателю, а затем, аналогично, clamp() по 0, размеру строки и размеру подстроки, передав полученный результат со сдвигом по указателю вторым параметром в конструктор класса? Так нельзя?

      Про findSubString() уже всё сказали выше. Опять же, я бы тоже не позволял просто так в метод передавать пустой аргумент в качестве строки поиска или делал бы такую проверку отдельно в самом начале и возвращал 0.

      Я не особый специалист по плюсам, возможно, где-то херню написал.
      Ответить
      • Не понимаю, в языке же есть поддержка ООП, почему её не используют?
        Не понимаю, в языке же есть поддержка процедурного программирования, почему её не используют?
        Не понимаю, в языке же есть поддержка ФП, почему её не используют?
        Не понимаю, в языке же есть поддержка АОП, почему её не используют?
        Не понимаю, в языке же есть поддержка Си, почему её не используют?
        Не понимаю, в языке же есть поддержка макросов, почему её не используют?
        Не понимаю, в языке же есть поддержка шаблонов, почему её не используют?
        Не понимаю, в языке же есть поддержка комплексных чисел, почему её не используют?

        Как же без всего этого со строками то раьотать?
        Ответить
        • А самое главное - почему тут не используется функция Бесселя? Её что, просто так в стандарт добавляли?
          Ответить
          • в стандартную либу добавили Бесселя, а mysql_real_escape не добавили. Почему?
            Ответить
            • std::quoted уже есть, осталось дождаться std::real_quoted.
              Ответить
              • мы уже обсуждали, да) причем он там так красиво сделан, что его можно поверх стрима навернуть вроде
                Ответить
              • А функций для работы со строками, типа упперкасе нету.

                Какой C++ )))
                Ответить
                • А зачем нужны функции для работы со строками, если строк нет?
                  Ответить
                  • А с чем тогда std:quoted роботает?
                    Ответить
                    • С массивами какой-то хуйни.
                      Ответить
                      • да там все алгоритмы с какой-то херней работают. Проще цикл написать, чем у кого-то занимать чем алгоритмы заюзать. Поневоле скриптушатникам завидовать начинаешь.
                        Ответить
                        • У скриптушатников тоже не у всех всё гладко. В том же js куда не сунься, везде свой dosomething.js, а стандартная либа настолько нищая, что поневоле понимаешь, почему люди всякие реакты и ноды так любят.
                          Ответить
        • Очень смешно )

          Ну вы тогда или крестик снимите, или штаны наденьте ) Или используйте ООП, или нет. А то набрали классов, а что с ними делать — хз )
          Ответить
      • Метода length() нет за ненадобностью. Что он должен возвращать? Кол-во кодепоинтов? Где это может потребоваться? Есть lengthInBytes(), который считается как разность указателей.

        Пустые строки и впрямь никто не рассматривал. Возможно в тестах бы и проверили, но тестов нет. Любой, кто будет передавать пустые строки - ССЗБ.

        subString() отсчитывает кодепоинты и выдергивает подстроку, передавая указатели в конструктор. Считаю, что передавать позицию в кодепоинтах также бессмысленно как и считать в них длину строки.
        clamp в 2005 не было. Описанный алгоритм не понял, почитаю позже.
        Кстати проблема с тормозами решилась добавлением версии subString() с итераторами.
        Ответить
        • > Пустые строки и впрямь никто не рассматривал. Возможно в тестах бы и проверили, но тестов нет. Любой, кто будет передавать пустые строки - ССЗБ.

          Как же вы можете доверять работе написанного кода, если у вас все предусловия прописаны неявно и никак не контролируются? Вы же не будете рассказывать каждому новому программисту о том, какая специфика работы каждого из написанных методов? ) Или у вас подробная документация есть? Но даже если так, документацию к классам читают обычно, когда что-то не работает, по-хорошему, интерфейс должен работать предсказуемым образом )
          Да, вряд ли кто-то явно будет передаст указатели друг на друга в качестве параметров, но ведь любая ошибка в связанном коде — и они могут там оказаться.

          Я понимаю, что это не ваш код, но и защищать его по принципу «это не код небезопасный, а программист глупый» тоже не очень правильно )

          > subString() отсчитывает кодепоинты и выдергивает подстроку, передавая указатели в конструктор. Считаю, что передавать позицию в кодепоинтах также бессмысленно как и считать в них длину строки.

          Я понял, ошибся, перепутал размеры сдвига у итератора с переданным размером строки.

          > clamp в 2005 не было.
          Он реализуется в одну-две строки ) Но не суть.
          Ответить
    • В плюсах-то уже можно пользоваться std::string для utf-8? Или надо С++26 ждать?
      Ответить

    Добавить комментарий