1. Си / Говнокод #18563

    +1000

    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
    int cutNCountLt3(char *in, char *out, long min) {
        int lt3 = 0;
        char *i = in, *j = in, *k = out;
    
        while (*j && *i) {
            j = i;
            while (*j != ' ' && *j)
                *k++ = *j++;
    
            *k++ = *j;
    
            int len = j - i;
            lt3 += len < 3;
    
            if (len < min)
                *(k -= len + 1) = '\0';
    
            i = j + 1;
        }
    
        return lt3;
    }

    К #9911
    А конкретнее http://govnokod.ru/9911#comment295215

    После нескольких ревизий в комментах, подумал, что наложить здесь будет лучше... Прошу любить, но не жаловать

    Запостил: Elvenfighter, 03 Августа 2015

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

    • А также с использованием этой вашей стандартной библиотеки:
      int cutNCountLt3(char *in, char *out, long min) {
          int lt3 = 0;
          char *i = in, *j = in, *k = out;
      
          while (*j && *i) {
              j = strchr(i, ' ');
              if (! j)
                  j = i + strlen(i);
      
              long len = j - i;
              lt3 += len < 3;
      
              if (len >= min) {
                  memcpy(k, i, len + 1);
                  k += len + 1;
              }
      
              i = j + 1;
          }
      
          return lt3;
      }
      Ответить
    • А к этому коду ещё один костыль вначале:
      out[0] = in[0];
      Ответить
    • > *(k -= len + 1) = '\0';
      Нафига? Можно же просто k -= len + 1, а нолик один раз в конце подклеить перед самым возвратом.
      Ответить
      • проблема сего говнокода в том, что после цикла k может указывать как на конец строки так и ЗА конец строки. В 99% случаев делать
        *k = '\0';
        безопасно.
        Однако есть одно исключение, которое портит малину: в случае если in и out одинакового размера (например in == out), и ниодного слова не было вырезано, то произойдёт запись за пределом выделенной памяти.
        Ответить
        • А если мы вот этим костылём k[ k == out ? 0 : -1] = '\0' будем его втыкать?
          Ответить
          • Если ни одного слова не скопировалось, k == out и k[0] = '\0'. Ок.
            Если последнее слово скопировалось вместе с пробелом "foo ", то k указывает за пробел, k>out, k[-1] = '\0', пробел затирается ноликом. Ок.
            Если последнее слово скопировалось вместе с ноликом "foo\0", то k указывает на нолик, k>out, k[-1] = '\0', ничего не менется. Ок.

            Вроде проблем нету...
            Ответить
            • Вот иллюстрация, почему так делать нельзя: http://ideone.com/5NJbR2

              У меня выдало:
              in [27]: 1 12 123 1234 12345 123456
              out [27]: 0x8d41008 .. 0x8d41022
              >>> after loop k: 0x8d41023
              out [27]: 1 12 123 1234 12345 123456


              Конечо можно сказать пользователю, чтоб аллоцировал буфер на один больше исходной строки
              Ответить
              • k == out? нет. Значит пишем нолик в k[-1]. И всё ок же, никакого выхода за границу. Разве нет?
                Ответить
                • Да, всё правильно.
                  Ответить
                • I want to send you an award for most helpful innrteet writer.
                  Ответить
                • Wow, your post makes mine look <a href="http://kpdxnhd.com">feeleb.</a> More power to you!
                  Ответить
                • Imiepssrve brain power at work! Great answer! http://vebyuvwtqf.com [url=http://slqaiahn.com]slqaiahn[/url] [link=http://eetkqqdpfa.com]eetkqqdpfa[/link]
                  Ответить
                • You've really captured all the estsaeinls in this subject area, haven't you? http://kpncmfyi.com [url=http://ctpdvyfnp.com]ctpdvyfnp[/url] [link=http://afashnqugrt.com]afashnqugrt[/link]
                  Ответить
              • Стоп, туплю
                Ответить
    • Олимпиадники такой код обычно пишут.
      Ответить
      • Тут, собственно, и проходит очередной этап специальной олимпиады
        Ответить
        • Wow, your post makes mine look feeebl. More power to you!
          Ответить
        • That hits the target dead <a href="http://cyjgduoiex.com">cenert!</a> Great answer!
          Ответить
        • An answer from an expert! Thanks for conibtruting. http://ifyrcs.com [url=http://xdfwejpianx.com]xdfwejpianx[/url] [link=http://gowakbutg.com]gowakbutg[/link]
          Ответить
        • Whoever edits and puhlisbes these articles really knows what they're doing. http://tydcaerk.com [url=http://honblqnu.com]honblqnu[/url] [link=http://iljasohexkd.com]iljasohexkd[/link]
          Ответить

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