[英]What is the meaning/logic of if(len …) in the following bit of code?
這是來自chux對以下問題的回答: 如何從文件中獲取字符串並將其存儲在2D char數組中,然后將該2D char數組與C中的字符串進行比較?
去除潛在的拖尾“ \\ n”
size_t len = strlen(buf); if (len && buf[len-1] == '\\n') buf[--len] = '\\0';
我了解if語句的第二部分(檢查buf [len-1] =='\\ n'),但不認為我了解其中的if(len)部分...是否只是在檢查是否存在實際上是緩沖區中的任何內容都為非零長度(如果是,則strlen返回0的情況怎么會出現?)還是其他?
空字符串的長度為0
。
以下代碼將導致len
為0
:
const char * str = "";
size_t len = strlen(str);
因此我們必須在訪問str[len-1]
之前檢查它,以避免整數環繞。
請注意,由於結尾為'\\0'
,因此保存str
的緩沖區的長度為1
,因此內存將如下所示:
buf --> [ '\0' ]
僅當大於零時才可以對數組建立索引。 因此訪問buff[len-1]
len
必須大於零,否則,如果len為零,則len - 1
將是由SIZE_MAX
定義的非常大的數字,並且buff [-1]是錯誤。 語句if (len && buff[len-1]=='\\n')
結合了兩個條件:
首先檢查len > 0
,然后檢查buff[len-1] == '\\n'
。
上面給出的if
語句僅表示以下含義: if( (len > 0) && (buff[len-1] == '\\n'))
while (i < 100 && fgets(buf, sizeof buf, f) != NULL ) {
// Lop off the potential tailing '\n'
size_t len = strlen(buf);
if (len && buf[len-1] == '\n') buf[--len] = '\0';
它只是檢查緩沖區中的長度是否實際上為非零長度
是。
在嘗試buf[len-1]
防止訪問buf[]
超出范圍之前,代碼正在測試len != 0
。
@喬納森·萊夫勒
(如果是這樣,怎么會出現strlen返回0的情況?)
防御性編碼:讀取的行可能以空字符開頭。
先前的代碼具有fgets(buf, sizeof buf, f)
,它讀取一行然后形成一個字符串 。 在C標准庫1中 ,輸入行是直到'\\n'
並包括'\\n'
的字符。 空字符對輸入沒有特殊的意義,就像其他字符一樣。 用fgets()
讀取一行並將其保存在buf[]
,將附加一個空字符 。 size_t len = strlen(buf);
返回基於第一個空字符的長度,不一定是附加的字符 。
如果文本文件行是
'\0', 'a', 'b', 'c', '\n'
然后fgets(buf, ...)
將導致buf[]
為
'\0', 'a', 'b', 'c', '\n', '\0'
並且len == 0
。
ASCII文本文件通常包含空字符 。 他們的存在通常是錯誤的或邪惡的(黑客利用)。 空字符在UTF-16文本文件中很常見,但是使用有問題的代碼讀取這樣的文件也有其他麻煩。
1 “文本流是由行組成的有序字符序列,每行由零個或多個字符加上一個終止換行符組成。最后一行是否需要終止換行符由實現定義。” C11dr§7.21.22
size_t is the unsigned integer type of the result of sizeof , alignof (since C11) and offsetof, depending on the data model.
我認為您在檢查方面是正確的。 size_t是無符號整數類型,因此它正在檢查條件以便進行其他檢查和buf[--len]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.