Преобразовать шестнадцатеричную строку в целое число эффективно в C?

Элемент, который вы пытались найти, не был в DOM , когда ваш скрипт работал.

Позиция вашего DOM-зависимого скрипта может оказать глубокое влияние на его поведение. Браузеры анализируют HTML-документы сверху донизу. Элементы добавляются в DOM, и сценарии выполняются (как правило), когда они встречаются. Это означает, что порядок имеет значение. Как правило, скрипты не могут найти элементы, которые появляются позже в разметке, потому что эти элементы еще не добавлены в DOM.

Рассмотрим следующую разметку; сценарий # 1 не находит

, а сценарий # 2 преуспевает:


test div

Итак, что вы должны делать? У вас есть несколько вариантов:


Вариант 1: Переместите свой скрипт

Переместите свой скрипт дальше по странице, перед закрывающим тегом тела. Организованный таким образом остальная часть документа анализируется до того, как будет выполнен ваш скрипт:


  
  

Примечание: размещение скриптов внизу как правило, считается лучшей практикой .


Вариант 2: jQuery's ready()

Отмените свой сценарий до тех пор, пока DOM не будет полностью проанализирован, используя ready() :



Примечание. Вы можете просто привязать к DOMContentLoaded или window.onload, но у каждого есть свои оговорки. jQuery ready() предоставляет гибридное решение.


Вариант 3: Делегирование событий

Делегированные события имеют преимущество в том, что они могут обрабатывать события из элементов-потомков, которые будут добавлены в документ позже.

blockquote>

Когда элемент вызывает событие (при условии, что это bubbling g6], и ничто не останавливает его распространение), каждый родитель в родословной этого элемента также получает событие. Это позволяет нам привязать обработчик к существующему элементу и примерным событиям, когда они пузырятся от его потомков ... даже те, которые добавлены после присоединения обработчика. Все, что нам нужно сделать, это проверить событие, чтобы узнать, был ли он поднят нужным элементом и, если да, запустите наш код.

jQuery on() выполняет эту логику для нас. Мы просто предоставляем имя события, селектор для желаемого потомка и обработчик событий:



Примечание: Обычно этот шаблон зарезервированы для элементов, которые не существовали во время загрузки или , чтобы избежать прикрепления большого количества обработчиков. Также стоит отметить, что, пока я прикреплял обработчик к document (для демонстрационных целей), вы должны выбрать ближайшего надежного предка.


Вариант 4: Атрибут defer

Используйте атрибут defer в

Для справки, вот код из этого внешнего скрипта :

document.getElementById("test").addEventListener("click", function(e){
   console.log("clicked: %o", this); 
});

Примечание: атрибут defer, безусловно, кажется , как волшебная пуля , но важно знать об оговорках ... 1. defer может использоваться только для внешних скриптов, т. е. для тех, у кого есть атрибут src. 2. знать о поддержке браузера , то есть: ошибка реализации в IE & lt; 10

23
задан Peter Cordes 10 May 2016 в 20:22
поделиться

8 ответов

Вы хотите strtol или strtoul . См. также страница справочника

Unix
39
ответ дан Peter Cordes 29 November 2019 в 00:37
поделиться

@Eric

я на самом деле надеялся видеть, что мастер C отправляет что-то действительно, охлаждает, вид подобных, что я сделал, но менее подробный, все еще делая его "вручную".

ну, я не гуру C, но здесь - то, что я придумал:

unsigned int parseHex(const char * str)
{
    unsigned int val = 0;
    char c;

    while(c = *str++)
    {
        val <<= 4;

        if (c >= '0' && c <= '9')
        {
            val += c & 0x0F;
            continue;
        }

        c &= 0xDF;
        if (c >= 'A' && c <= 'F')
        {
            val += (c & 0x07) + 9;
            continue;
        }

        errno = EINVAL;
        return 0;
    }

    return val;
}

у меня первоначально было больше bitmasking, продолжающийся вместо сравнений, но я серьезно сомневаюсь, что bitmasking немного быстрее, чем сравнение на современных аппаратных средствах.

1
ответ дан Derek Park 29 November 2019 в 00:37
поделиться

, Почему решение для кода, которое работает, будучи проваленным? Несомненно, это ужасно...

, Возможно, потому что, а также быть ужасным это не является образовательным и , не делает работа. Кроме того, я подозреваю, что как я, большинство людей не имеет права редактировать в настоящее время (и оценка по необходимому разряду - никогда не будет).

использование массива может быть хорошо для эффективности, но это не упоминается в этом коде. Это также не уделяет внимания верхнему регистру и нижнему регистру, таким образом, это не работает на пример, предоставленный в вопросе. FFFFFFFE

1
ответ дан itj 29 November 2019 в 00:37
поделиться

@Eric

, Почему решение для кода, которое работает, будучи проваленным? Несомненно, это ужасно и не могло бы быть самым быстрым способом сделать это, но это более поучительно что, говоря "strtol" или "sscanf". При попытке его сами, Вы узнаете что-то о том, как вещи происходят под капотом.

я действительно не думаю, что Ваше решение должно было быть провалено, но мое предположение относительно того, почему это происходит, то, потому что это менее практично. Идея с голосованием состоит в том, что "лучший" ответ будет плавать к вершине, и в то время как Ваш ответ мог бы быть более поучительным о том, что происходит под капотом (или способ, которым это могло бы произойти), это - определенно не лучший способ проанализировать шестнадцатеричные числа в производственной системе.

Снова, я не думаю, что существует что-то не так с Вашим ответом с образовательной точки зрения, и я, конечно, не был бы (и не сделал), проваливают его. Не становитесь нежелательными и прекращайте отправлять просто, потому что некоторым людям не нравился один из Ваших ответов. Это происходит.

я сомневаюсь, что мой ответ заставляет Вас чувствовать немного лучше о Вашем проваливаемом, но я знаю, что это - особенно не забава, когда Вы спрашиваете, почему что-то проваливается, и никто не отвечает .

2
ответ дан Community 29 November 2019 в 00:37
поделиться

Если у Вас нет stdlib тогда, необходимо сделать это вручную.

unsigned long hex2int(char *a, unsigned int len)
{
    int i;
    unsigned long val = 0;

    for(i=0;i<len;i++)
       if(a[i] <= 57)
        val += (a[i]-48)*(1<<(4*(len-1-i)));
       else
        val += (a[i]-55)*(1<<(4*(len-1-i)));

    return val;
}

Примечание: Этот код принимает прописной A-F. Это не работает, если len - вне Вашего самого длинного целого числа 32 или 64 бита, и нет никакого обнаружения ошибок для недопустимых шестнадцатеричных символов.

8
ответ дан Markus Safar 29 November 2019 в 00:37
поделиться

Попробуйте это:

#include <stdio.h>
int main()
{
    char s[] = "fffffffe";
    int x;
    sscanf(s, "%x", &x);
    printf("%u\n", x);
}
16
ответ дан Jared Burrows 29 November 2019 в 00:37
поделиться

Поскольку более крупное Шестнадцатеричное число представляет в виде строки как в примере, я должен был использовать strtoul.

2
ответ дан 29 November 2019 в 00:37
поделиться

Как записано прежде, эффективность в основном зависит от того, для чего каждый оптимизирует.

, Когда optiming для строк кода, или просто работающий в среде без полностью оборудованной стандартной библиотеки одна быстрая и грязная опция могла быть:

// makes a number from two ascii hexa characters
int ahex2int(char a, char b){

    a = (a <= '9') ? a - '0' : (a & 0x7) + 9;
    b = (b <= '9') ? b - '0' : (b & 0x7) + 9;

    return (a << 4) + b;
}

... больше в подобном потоке здесь: https://stackoverflow.com/a/58253380/5951263

0
ответ дан 29 November 2019 в 00:37
поделиться
Другие вопросы по тегам:

Похожие вопросы: