Onaltılık dizge (char []) int'e dönüştürülsün mü?


Yanıtlar:


209

Denedin strtol()mi

strtol - dizgeyi uzun bir tam sayıya dönüştürür

Misal:

Durumunda sayının dize gösterimi bir ile başlar 0xönek, tek gereken temel olarak 0 kullanmalıdır:

(16 gibi açık bir taban belirtmek de mümkündür, ancak artıklık getirmeyi önermem.)


4
Eğer hexstring soruda belirtildiği gibi her zaman a ile tanıtılmışsa, bunun yerine "0x"sadece kullanmalısınız . 016
Jens Gustedt

16
@KelvinHu cplusplus.com'a güvenmeyin, saçmalık. Varsa, cppreference.com'a gidin .

1
@KelvinHu Bu sitede teknik olarak yanlış veya gevşek bir şekilde ifade edilmiş birçok bilgi var ve SO'nun etrafında C ++ programcıları görürseniz, hepsi bu nedenle ona güvenmekten vazgeçecektir.

1
@ H2CO3 Tamam, anlıyorum, C ++ 'da yeniyim , bu yüzden bunu google ile araştırıyorum ve cplusplus.com'u en ön konuma yerleştiriyor. Bilgileriniz için gerçekten teşekkürler.
Kelvin Hu 13

3
Bir yan not strtolsize longçok büyük bir altıgenle uğraşırken harika olan yazımı verir . Daha büyük altıgenler için yazı strtolltipi long longiçin kullanın .
Steven Lu

20

Veya kendi uygulamanıza sahip olmak istiyorsanız, bu hızlı işlevi bir örnek olarak yazdım:


1
Mikrodenetleyiciler gibi sınırlı kaynaklara sahip platformlar için çok kullanışlıdır.
Mubin Icyer

19

Bunun gibi bir şey yararlı olabilir:

Man sscanf oku


1
Bu tanımsız davranışa neden olur %x, bir unsigned int. Ve bunu düzeltseniz bile, dizenin temsil ettiği sayı daha büyükse UINT_MAX, yine tanımsız bir davranış olur
MM

10

Bunun bir ip olduğunu varsayarsak, strtol'e ne dersiniz ?


Başlangıçta strtol yerine strtod (-> double) ile bağlantılıydım. Sanırım ben düzenleme yaparken birisi gördü.
James McLaughlin

Pekala, bu pek bir hata değil ... derleyici, bir int. +1, btw.

Bir çift bütün olası değerleri 32 bit tamsayı teneke saklayabilir sanmıyorum (? Eğer bu doğruysa aslında, kayan nokta sayı gösterimine değil% 100 değilim bilen var mı.)
James McLaughlin

4
@JamesMcLaughlin Yapabilir. 64 bitlik bir IEEE çiftinin integral doğruluğu yaklaşık 2 ^ 53'tür.

Ayrıntı, "64 bitlik bir IEEE çiftinin integral doğruluğu yaklaşık 2 ^ 53'tür." ve biraz işaret. Böylece başa çıkabilir int54_tve uint53_t.
chux - Monica'yı yeniden etkinleştir

5

strtolEn iyi yanıtın önerdiği gibi libc'ye sahipseniz kullanın . Bununla birlikte, özel şeyleri seviyorsanız veya libc veya benzeri olmayan bir mikro denetleyicideyseniz, karmaşık dallanma içermeyen biraz optimize edilmiş bir sürüm isteyebilirsiniz.

Bit kaydırma büyüsü şu şekildedir: Sadece son 4 biti kullanın, ancak rakam değilse, 9 ekleyin.


Bir şansınız olursa "v =" satırının nasıl çalıştığını biraz daha detaylandırabilir misiniz? İşlevinizi kendi amaçlarım için aşağıdaki şekilde uygulamayı başardım:unsigned long long int hextou64(char *str) { unsigned long long int n = 0; char c, v; for (unsigned char i = 0; i < 16; i++) { c = *(str + i); v = (c & 0xF) + (c >> 6) | ((c >> 3) & 0x8); n = (n << 4) | (unsigned long long int)v; } return n; }
iamoumuamua

Bakalım bunu hala bir araya getirebilir miyim ^^ Oldukça zor sanırım .. Önerme: '0' - '9' hepsi '0011 ????' ile başlıyor ikili olarak. 'A' - 'F' tümü '0100 ????' ile başlar ikili olarak. Dallanmayı önlemek için bu bilgiyi kullanabiliriz. (c & 0xF) → sadece son dört bit değeri içerir. Bu zaten '0' - '9' için doğru değerdir. 'A' - 'F' durumunda, doğru değeri elde etmek için bir ondalık 9 eklemeliyiz. (Örneğin, Hex C 0011 ile biter. 3. Ama biz 12 istiyoruz. Bu nedenle 9. eklemeliyiz. (c >> 6) | ((c >> 3) & 0x8)→ harf olması durumunda 9, ondalık olması halinde 0 olarak değerlendirilir. Evet, oldukça hacky :)
LimeRed

3

Aşağıdaki kod bloğunu deneyin, benim için çalışıyor.

Çıktı:


3

Bir süre araştırdıktan ve strtol'ün oldukça yavaş olduğunu öğrendikten sonra, kendi fonksiyonumu kodladım. Yalnızca büyük harfler için çalışır, ancak küçük harf işlevselliği eklemek sorun olmaz.

Kullanım:

1 çünkü dönüştürmek istediğimiz onaltılık uzaklık 1'den başlar ve 8, çünkü bu onaltılık uzunluktur.

Hız testi (1.000.000 çağrı):


2

Hızlı ve kirli bir çözüm:

Girişinizin doğru olduğundan, doğrulama dahil edilmediğinden emin olmalısınız (C olduğu söylenebilir). İyi ki oldukça kompakt, hem "A" dan "F" ye hem de "a" dan "f" ye kadar çalışıyor.

Yaklaşım, ASCII tablosundaki alfabe karakterlerinin konumuna dayanır, örneğin Wikipedia'ya göz atalım ( https://en.wikipedia.org/wiki/ASCII#/media/File:USASCII_code_chart.png ). Uzun lafın kısası, sayılar karakterlerin altındadır, bu nedenle sayısal karakterler (0'dan 9'a), kodu sıfıra çıkararak kolayca dönüştürülür. Alfabetik karakterler (A'dan F'ye), son üç bit dışında sıfırlanarak (etkin bir şekilde büyük veya küçük harfle çalışmasını sağlayarak), bir çıkararak (çünkü bit maskelemeden sonra alfabe birinci konumda başlar) ve on eklenerek ( çünkü A - F, onaltılık kodda 10. - 15. değeri temsil eder). Son olarak, kodlanmış sayının alt ve üst yarım baytını oluşturan iki rakamı birleştirmemiz gerekiyor.

Burada aynı yaklaşımla gidiyoruz (küçük varyasyonlarla):


1
Cevabı gönderdikten sonra, @LimeRed'in çok sevimli gönderisini kaçırdığımı öğrendim
Simon

1

Bu, onaltılı içeren char dizisini, fazladan kitaplık gerektirmeyen bir tamsayıya doğrudan dönüştürmek için bir işlevdir:


0

Kullanmadan Onaltılık / Ondalık dönüşüm yapmak için bir kitaplık yaptım stdio.h. Kullanımı çok basit:

İlk dönüşümden önce, dönüşüm için kullanılan diziyi şu şekilde tanıtın:

İşte github'daki bağlantı: https://github.com/kevmuret/libhex/


0

Ben de benzer bir şey yaptım, bunun aslında benim için çalışmasına yardımcı olabileceğini düşünüyorum

burada sadece 8 karakterlik bir dizi aldım. Eğer 'a' dan 'f' ye eşdeğer onaltılık değerleri vermek için benzer bir mantık ekleyebilirsiniz, bunu yapmadım çünkü ihtiyacım olmadı.


-5

Bunun gerçekten eski olduğunu biliyorum ama çözümlerin çok karmaşık göründüğünü düşünüyorum. Bunu VB'de deneyin:

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.