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

    +144

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    /* возвращает в buf последние 4 символа имени файла filename */
    void getfileext(unsigned char *buf, unsigned char *filename)
    {
        int i, j;
    
        for (i = strlen((char *) filename) - 4, j = 0; i < strlen((char *) filename); i++, j++)
            buf[j] = filename[i];
    
        return;
    }

    Запостил: angry C nerd, 06 Апреля 2011

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

    • strcpy(buf, filename[strlen(filename) - 4]);

      А если длина имени меньше 4?
      Ответить
      • undefined behavior, memory corruption, segfault на выбор :3
        Ответить
        • первым двум вариантам не суждено сбыться:
          будет простое копирование мусора в начале, главное чтобы в buf было достаточно места, но это никак не связано с длиной filename. с третьим - может быть.
          Ответить
          • Суждено.
            Ответить
            • только в силу кривости кода
              Ответить
              • Выход за пределы массива — это уже UB. А как оно будет проявляться, ошибкой доступа, зацикливанием, возвратом просто неверных данных, неправильной работой следующих операторов, исключением, остановом процессора — это уже детали, зависящие от окружения и случая.
                Ответить
                • Что-то я не припомню, чтобы выход за пределы памяти по чтению приводил, скажем, к зацикливанию.
                  Ответить
                  • Ну, например, сегментная организация памяти, выскочили в соседний сегмент. А strlen предполагает, что вся строка в одном сегменте и инкрементирует только смещение. И в этом сегменте нулевых байтов не оказалось.
                    Ответить
          • Ступил. Мне запись по [i] приглючилась
            Ответить
      • Тогда приду Я!!!
        Ответить
      • код на С в исполнении Тараса ... дорогого стоит :)))
        Ответить
      • Правильный ответ - Access violation.
        Ответить
      • Как бэ лучше вот так ИМХО:
        int len = strlen(filename);
        if (len >= 4)
        strcpy(buf, filename[len - 4]);
        else
        buf[0] = '\0';
        Ответить
        • filename[len - 4] возвращает char, а не char*.
          длинна известна, так что можно обойтись memcpy
          strlen возвращает size_t, а не int

          size_t len = strlen(filename);
          if (len >= 4)
            memcpy(buf, filename + len - 4, 5);
          else
            *buf = 0;
          Ответить
        • TarasB & SadKo :) хватит ошибки копировать. Второй параметр strcpy должен быть указателем, а не символом.
          Ответить
    • Как все бросились копировать последние 4 символа. А ничего, что уже 1-я строка (особенно в контексте имени getfileext) — говнокод?

      Сигнатура функции тоже доставляет.
      Ответить
      • Особенно интересно, что автор хотел сказать своими unsigned char?
        Ответить
        • Неважно, хотел ли автор получить последние 4 символа или «расширение файла», но функция могла бы просто возвращать указатель. Например:
          unsigned char * getfileext(unsigned char *filename)
          {
              size_t len = strlen((char *) filename);
              return len > 4 ? filename + (len - 4) : filename;
          }
          Ответить
    • 100% ГК - работать не будет нормально даже для 8:3.
      readme
      stdio.h
      я уж не говорю про длинные имена: test.local
      и совсем уж все плохо для файла/папки ".." например
      Ответить
      • он рассчитан на "правильные" имена формата *.ХХХ :)
        Ответить
        • нуу имена формата *.хххх так же правильные как и *.хх
          Ответить
    • все-таки говно.
      Ответить
    • Потом парень заканчивал, снимал презик, бросал его на пол, а эта самка ожидала следующего героя. Иногда за вечер через Наткину вагину «проходило» до двух десятков парней!
      Ответить

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