RM新时代网站-首页

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線(xiàn)課程
  • 觀(guān)看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

如何判斷一段字符串的長(zhǎng)度

魚(yú)鷹談單片機(jī) ? 來(lái)源:魚(yú)鷹談單片機(jī) ? 2024-08-12 17:42 ? 次閱讀

來(lái)源:公眾號(hào)【魚(yú)鷹談單片機(jī)

作者:魚(yú)鷹Osprey

ID :emOsprey

這周課上介紹斷言實(shí)現(xiàn)的時(shí)候,莫名其妙被斷言的真真假假搞暈了。

起因是看到一段關(guān)于判斷一段字符串的長(zhǎng)度,使用了 ASSERT 方式,原文大概是這樣寫(xiě)的:

#define AES256_KEY                      "0123456789ABCDEF0123456789ABCDEF"  /* 必須等于 32 字節(jié) */
#define AES256_IV                       "0123456789ABCDEF"                  /* 必須等于 16 字節(jié) */
extern void Assert_Failed(uint8_t *func, uint32_t line);
#define ASSERT(expr)            ((expr) ? (void)0U : Assert_Failed((uint8_t *)__func__, __LINE__))
voidfunc()
{
  ASSERT(sizeof(AES256_KEY) != 32);
     ASSERT(sizeof(AES256_IV) != 16);
}

一開(kāi)始總以為這種寫(xiě)法沒(méi)問(wèn)題,畢竟這么簡(jiǎn)單,模擬調(diào)試的時(shí)候確實(shí)也不會(huì)報(bào)錯(cuò)(打開(kāi)了斷言情況下)。

為了課上測(cè)試一下靜態(tài)編譯報(bào)錯(cuò)的效果,卻發(fā)現(xiàn)始終有些問(wèn)題,不該報(bào)錯(cuò)的時(shí)候報(bào)錯(cuò)了。

#define STATIC_ASSERT(...)      extern char (*_do_assert(void)) [sizeof(char[1 - 2*!(__VA_ARGS__)])]

為了方便,魚(yú)鷹直接用 MDK 測(cè)試了 sizeof 字符串的結(jié)果,發(fā)現(xiàn)確實(shí)也是16(0x10)

285aa6f4-4d44-11ef-b8af-92fbcf53809c.png

然后我就困在了這兩個(gè)前提上,STATIC_ASSERT 報(bào)錯(cuò)始終有問(wèn)題。

#define AES256_KEY                      "0123456789ABCDEF0123456789ABCDEF"  /* 必須等于 32 字節(jié) */
#define AES256_IV                       "0123456789ABCDEF"                  /* 必須等于 16 字節(jié) */
extern void Assert_Failed(uint8_t *func, uint32_t line);
#define ASSERT(expr)            ((expr) ? (void)0U : Assert_Failed((uint8_t *)__func__, __LINE__))


#define STATIC_ASSERT(...)      extern char (*_do_assert(void)) [sizeof(char[1 - 2*!(__VA_ARGS__)])]
void func()
{
     ASSERT(sizeof(AES256_KEY) != 32);
     ASSERT(sizeof(AES256_IV) != 16);
STATIC_ASSERT(sizeof(AES256_IV)!=16);
}

286bd05a-4d44-11ef-b8af-92fbcf53809c.png

調(diào)試的時(shí)候,STATIC_ASSERT 報(bào)錯(cuò),但是 ASSERT不報(bào)錯(cuò)

這讓魚(yú)鷹百思不得其解,一開(kāi)始以為兩個(gè)宏邏輯相反,不都是邏輯值為假時(shí)報(bào)錯(cuò)。

但是通過(guò)分析宏發(fā)現(xiàn),都是假的時(shí)候報(bào)錯(cuò)。

那肯定哪里分析有問(wèn)題了。

因?yàn)榫幾g器如果能得到結(jié)果為真,ASSERT可能無(wú)法形成代碼,即為空(void)0U。

因此魚(yú)鷹使用了一個(gè)變量作為中間值,強(qiáng)行讓編譯器生成斷言相關(guān)的代碼,才算是發(fā)現(xiàn)了問(wèn)題。

void func()
{
uint32_tsize = sizeof(AES256_IV); 

    ASSERT(sizeof(AES256_KEY) != 32);
    ASSERT(size!=16);
    STATIC_ASSERT(sizeof(AES256_IV) != 16);
}

這個(gè)size 的值竟然是 17,而不是 16,難怪初始代碼不報(bào)錯(cuò),17 != 16,當(dāng)然為真,當(dāng)然不報(bào)錯(cuò)。

但寫(xiě)代碼的人是希望這個(gè)字符串的長(zhǎng)度為始終是16(不包含null的情況下),而明顯代碼中使用sizeof 時(shí)計(jì)算了 null 的長(zhǎng)度。

所以代碼應(yīng)該這樣寫(xiě)才對(duì):

void func()
{
ASSERT(sizeof(AES256_KEY)==32);
ASSERT(sizeof(AES256_IV)==16);
STATIC_ASSERT(sizeof(AES256_IV)==16);
}

但是又因?yàn)榇a的sizeof 會(huì)計(jì)算null,因此需要去除這個(gè)數(shù):

void func()
{
ASSERT(sizeof(AES256_KEY) - 1==32);
ASSERT(sizeof(AES256_IV) - 1==16);
STATIC_ASSERT(sizeof(AES256_IV) - 1==16);
}

2884bafc-4d44-11ef-b8af-92fbcf53809c.png

這樣 STATIC_ASSERT 可以在編譯階段就可以判斷這個(gè)字符串的長(zhǎng)度是否符合要求,多一個(gè)、少一個(gè)字符都不行。

這個(gè)坑你們遇到過(guò)嗎?

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀(guān)點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 字符串
    +關(guān)注

    關(guān)注

    1

    文章

    578

    瀏覽量

    20506
  • 編譯器
    +關(guān)注

    關(guān)注

    1

    文章

    1623

    瀏覽量

    49108
  • 編譯
    +關(guān)注

    關(guān)注

    0

    文章

    657

    瀏覽量

    32852

原文標(biāo)題:被斷言罷了一道

文章出處:【微信號(hào):emOsprey,微信公眾號(hào):魚(yú)鷹談單片機(jī)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    請(qǐng)問(wèn)各位大神一段只讀亂序字符串能否排序輸出嗎

    請(qǐng)問(wèn)各位大神一段只讀亂序字符串能否排序輸出嗎
    發(fā)表于 05-14 12:45

    Labview之字符串長(zhǎng)度函數(shù)

    Labview之字符串長(zhǎng)度函數(shù),很好的Labview資料,快來(lái)下載學(xué)習(xí)吧。
    發(fā)表于 04-19 10:43 ?0次下載

    清華集訓(xùn)2017模擬之字符串

    一個(gè)字符串的權(quán)值是這個(gè)包含的不同字符個(gè)數(shù)。 給定個(gè)長(zhǎng)度為n的字符串,把它分為k個(gè)連續(xù)非空字段
    發(fā)表于 11-28 16:33 ?1399次閱讀

    字符串移位包含的問(wèn)題解決方案

    問(wèn)題:給定字符串s和t,判斷是否字符串t能通過(guò)將s移位后的字符串所包含。 方法 最簡(jiǎn)單的方法就是將s進(jìn)行循環(huán)移位,再
    發(fā)表于 11-29 10:05 ?1044次閱讀

    教你7個(gè)Python判斷字符串是否包含子的方法

    教你7個(gè)Python判斷字符串是否包含子的方法
    的頭像 發(fā)表于 08-17 10:52 ?5091次閱讀
    教你7個(gè)Python<b class='flag-5'>判斷</b><b class='flag-5'>字符串</b>是否包含子<b class='flag-5'>串</b>的方法

    什么是復(fù)制字符串?Python如何復(fù)制字符串

    連續(xù)幾篇文章都在寫(xiě) Python 字符串,這出乎我的意料了。但是,有的問(wèn)題,不寫(xiě)不行,特別是那種靈機(jī)動(dòng)想到的問(wèn)題,最后你發(fā)現(xiàn),很多人根本不懂卻又誤以為自己懂了。那就繼續(xù)刨根問(wèn)底,探究個(gè)明白吧
    發(fā)表于 11-25 10:32 ?3011次閱讀

    C語(yǔ)言總結(jié)_字符串全方位練習(xí)

    C語(yǔ)言字符串全方位練習(xí),涉及知識(shí)點(diǎn):字符串解析、大小寫(xiě)判斷字符串插入、字符串刪除、字符串排序、
    的頭像 發(fā)表于 08-14 09:41 ?1486次閱讀

    文詳解JavaScript字符串

    JavaScript字符串是原始值。此外,字符串是不可變的。這意味著如果你修改一個(gè)字符串,你總是會(huì)得到個(gè)新的字符串。原始
    的頭像 發(fā)表于 12-08 16:36 ?1193次閱讀

    字符串的格式化輸入和輸出

    字符串是內(nèi)存中一段連續(xù)的char空間,以’\0’(數(shù)字0)結(jié)尾。
    的頭像 發(fā)表于 02-24 14:34 ?1410次閱讀
    <b class='flag-5'>字符串</b>的格式化輸入和輸出

    字符串的相關(guān)知識(shí)

    TCL 中的數(shù)據(jù)類(lèi)型只有種:字符串。這些字符串可以是字母、數(shù)字、布爾值、標(biāo)點(diǎn)符號(hào)等特殊字符的組合。在某些特殊命令的作用下,字符串可以向其他
    的頭像 發(fā)表于 03-29 11:41 ?1145次閱讀

    Python 如何判斷字符串是否包含子

    方法 使用 字符串 對(duì)象的 find 方法,如果有找到子,就可以返回指定子字符串中的出現(xiàn)位置,如果沒(méi)有找到,就返回 -1 >> > "hello, python" . find
    的頭像 發(fā)表于 11-02 10:55 ?486次閱讀

    mysql字符串包含某個(gè)字符串

    MySQL是種開(kāi)源的關(guān)系型數(shù)據(jù)庫(kù)管理系統(tǒng),被廣泛用于構(gòu)建Web應(yīng)用程序和其他大型數(shù)據(jù)驅(qū)動(dòng)的應(yīng)用。在進(jìn)行MySQL數(shù)據(jù)庫(kù)查詢(xún)時(shí),經(jīng)常需要使用字符串包含操作,即判斷一個(gè)字符串是否包含另
    的頭像 發(fā)表于 11-16 14:52 ?3783次閱讀

    python輸出固定長(zhǎng)度字符串

    Python 是種強(qiáng)大而靈活的編程語(yǔ)言,具有許多用于處理字符串的功能。在 Python 中,有多種方法可以輸出固定長(zhǎng)度字符串。下面將詳細(xì)介紹這些方法。 方法
    的頭像 發(fā)表于 11-22 10:41 ?3290次閱讀

    oracle判斷字符串包含某個(gè)字符

    字符串操作是任何編程語(yǔ)言中都非常重要的部分,Oracle數(shù)據(jù)庫(kù)作為目前最常用的關(guān)系型數(shù)據(jù)庫(kù)之,也提供了豐富的字符串操作函數(shù)和方法。在本文中,我們將詳細(xì)解析如何在Oracle中
    的頭像 發(fā)表于 12-06 09:53 ?1.5w次閱讀

    labview中常用的字符串函數(shù)有哪些?

    在LabVIEW中,常用的字符串函數(shù)廣泛覆蓋了對(duì)字符串的各種操作,包括但不限于格式化、搜索、替換、連接、計(jì)算長(zhǎng)度等。以下是些常用的字符串
    的頭像 發(fā)表于 09-04 15:43 ?665次閱讀
    RM新时代网站-首页