以下代码中 if(len ....) 的 meaning/logic 是什么?
What is the meaning/logic of if(len ....) in the following bit of code?
这是来自 chux 对这里问题的回答:How to get the strings from a file and store in a 2D char array and compare that 2D char array with a string in C?
Lop off the potential tailing '\n'
size_t len = strlen(buf);
if (len && buf[len-1] == '\n') buf[--len] = '[=11=]';
我理解 if 语句的第二部分(检查 if buf[len-1] == '\n'),但不要以为我不理解它的 if (len) 部分...是它只是检查缓冲区中的任何内容是否实际上有一个非零长度(如果是这样,怎么会出现 strlen returns 0 的情况?)还是别的什么?
空字符串的长度为 0
。
以下代码将导致 len
成为 0
:
const char * str = "";
size_t len = strlen(str);
所以我们必须在访问之前检查它 str[len-1]
以避免整数回绕。
注意存放str
的缓冲区的长度是1
,因为尾随'[=18=]'
,所以内存看起来像这样:
buf --> [ '[=11=]' ]
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]
只有当某个值大于零时,您才能为数组建立索引。因此,要访问 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] = '[=10=]';
Is it simply checking if there's actually a non-zero length to whatever's in the buffer
是的。
代码正在测试 len != 0
,然后尝试 buf[len-1]
以防止访问 buf[]
超出范围。
(and if so, how can a situation where strlen returns 0 arise?)
防御性编码:读取的行可能以空字符.
开头
前面的代码有fgets(buf, sizeof buf, f)
,它读取行,然后形成一个字符串。在 C 标准库1 中,行 的输入是 '\n'
之前的字符。 空字符对输入没有特殊意义,它就像另一个其他字符一样。用fgets()
读取行并保存在buf[]
后,会附加一个空字符。 size_t len = strlen(buf);
return 基于第一个 空字符 的长度,不一定是附加的
如果文本文件行是
'[=11=]', 'a', 'b', 'c', '\n'
然后 fgets(buf, ...)
将导致 buf[]
为
'[=12=]', 'a', 'b', 'c', '\n', '[=12=]'
和len == 0
.
ASCII 文本文件很少包含 空字符。他们的存在通常是错误的或恶意的(黑客利用)。 空字符 在 UTF-16 文本文件中很常见,但读取带有相关代码的此类文件也有其他问题。
1 "A text stream is an ordered sequence of characters composed into lines, each line consisting of zero or more characters plus a terminating new-line character. Whether the last line requires a terminating new-line character is implementation-defined." C11dr §7.21.2 2
这是来自 chux 对这里问题的回答:How to get the strings from a file and store in a 2D char array and compare that 2D char array with a string in C?
Lop off the potential tailing '\n'
size_t len = strlen(buf); if (len && buf[len-1] == '\n') buf[--len] = '[=11=]';
我理解 if 语句的第二部分(检查 if buf[len-1] == '\n'),但不要以为我不理解它的 if (len) 部分...是它只是检查缓冲区中的任何内容是否实际上有一个非零长度(如果是这样,怎么会出现 strlen returns 0 的情况?)还是别的什么?
空字符串的长度为 0
。
以下代码将导致 len
成为 0
:
const char * str = "";
size_t len = strlen(str);
所以我们必须在访问之前检查它 str[len-1]
以避免整数回绕。
注意存放str
的缓冲区的长度是1
,因为尾随'[=18=]'
,所以内存看起来像这样:
buf --> [ '[=11=]' ]
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]
只有当某个值大于零时,您才能为数组建立索引。因此,要访问 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] = '[=10=]';
Is it simply checking if there's actually a non-zero length to whatever's in the buffer
是的。
代码正在测试 len != 0
,然后尝试 buf[len-1]
以防止访问 buf[]
超出范围。
(and if so, how can a situation where strlen returns 0 arise?)
防御性编码:读取的行可能以空字符.
开头前面的代码有fgets(buf, sizeof buf, f)
,它读取行,然后形成一个字符串。在 C 标准库1 中,行 的输入是 '\n'
之前的字符。 空字符对输入没有特殊意义,它就像另一个其他字符一样。用fgets()
读取行并保存在buf[]
后,会附加一个空字符。 size_t len = strlen(buf);
return 基于第一个 空字符 的长度,不一定是附加的
如果文本文件行是
'[=11=]', 'a', 'b', 'c', '\n'
然后 fgets(buf, ...)
将导致 buf[]
为
'[=12=]', 'a', 'b', 'c', '\n', '[=12=]'
和len == 0
.
ASCII 文本文件很少包含 空字符。他们的存在通常是错误的或恶意的(黑客利用)。 空字符 在 UTF-16 文本文件中很常见,但读取带有相关代码的此类文件也有其他问题。
1 "A text stream is an ordered sequence of characters composed into lines, each line consisting of zero or more characters plus a terminating new-line character. Whether the last line requires a terminating new-line character is implementation-defined." C11dr §7.21.2 2