下面的代码读取一行并返回行长。 lim是数组s []的长度。
当输入行长度为lim时,则s [lim] =' \ 0'。但是数组s []只有长度,从s [0]到s [lim-1]。它会导致缓冲区溢出吗?我测试了很多次,但代码似乎工作正常。
int getline(char s[], int lim)
{
int c, i;
for(i = 0; i < lim-1 && ( c = getchar())!= EOF && c!= '\n'; i++)
s[i] = c;
if( c == '\n') {
s[i] = c;
++i;
}
s[i] = '\0';
return i;
}
答案 0 :(得分:5)
'\0'
只是另一个角色。它存储在字符串的最后一个字符之后。
通常情况下,你可以逃脱&#34;写下缓冲区的末尾没有明显的伤害,但不要这样做。这是一个错误。
我曾经不得不调试包含这样的错误的程序。程序在一个缓冲区的末尾写入一个字节。在调试版本中,堆栈上有足够多的额外内容,单字节额外没有造成任何伤害;崩溃只发生在发布版本中,但调试器并没有真正起作用,因为它是非调试版本。这是为什么在&#34; debug&#34;中测试代码的好的一个例子。构建和发布版本(以您向用户提供的方式编译)。
答案 1 :(得分:0)
这是一个很好的例子,说明如何清楚地定义一个接口 - 它的输入和返回值;
&#34; int getline(char s [],int lim)&#34;
&#34; lim&#34;的一个可能的定义;是,要复制到s []的最大字符数,不包括终止空字符,即&#39; \ 0&#39; 例: char arr [] =&#34;你好&#34 ;; getline(arr,strlen(arr));
&#34; lim&#34;的另一个定义是,要复制到s []的最大字符数(包括终止空字符) 例: char arr [] =&#34;你好&#34 ;; getline(arr,sizeof(arr));
你似乎在假设&#34; lim&#34;的第二个定义。
答案 2 :(得分:0)
这是K&amp; R的“C编程语言”中的一个功能。这是第一章。它的工作原理是正确的。
考虑“猫”。这是一个四字符数组{'c','a','t','\ 0'}。字符串的长度是3。 如果s [] =“cat”则s [0] ='c',s [3] ='\ 0'。是吗?
srtlen返回的字符串长度或者你的字符数减一。分配数组以容纳所有4个字符。这就是'\ 0'在数组末尾的位置。
答案 3 :(得分:0)
不,它不会导致缓冲区溢出。实际上,'\ 0'表示NULL位置,它被视为数组的结尾。当您从数组的开头到结尾时,包含'\ 0'字符的最后一个位置将永远不会被视为包含有效数据的位置。
你可以使用while(index&lt; size)作为条件,或者使用while(array [position]!= NULL)来遍历所有数组