我是C编程语言的初学者,我对C编程语言中的空字符('\0'
)感到非常困惑。
根据以下程序,行的允许字符长度为10
(MAXLINE
定义为10
)。类似Navindren
长度为9的输入占用数组索引0
到8
,每当到达换行符时,它都会被添加到索引9
和i
增加1
。 i
现在为10
,s[10]
已分配'\0'
,s[10] = '\0'
。
这是一个混乱,这是怎么可能的,因为数组只是从索引0
- 9
分配空间?我试过引用很多在线资源,但解释还不够。
主要功能:
#include<stdio.h>
#define MAXLINE 10
int getline(char line[], int maxline);
void copy(char to[], char from[]);
main() {
int len; /*current line length*/
int max; /*maximum length seen so far*/
char line[MAXLINE]; /*current input line*/
char longest[MAXLINE]; /*longest line saved here*/
max = 0;
while ((len = getline(line, MAXLINE)) > 0) {
printf("%d\n", len);
if (len > max) {
max = len;
copy(longest, line);
}
}
if (max > 0) /* there was a line */ {
printf("%s", longest);
} else {
printf("No Lines Detected\n");
}
return 0;
}
Getline功能:
int getline(char s[], int lim) {
int c;
int i;
for (i = 0; i < MAXLINE - 1 && (c = getchar()) != EOF && c != '\n'; i++) {
s[i] = c;
}
if (c == '\n') {
s[i] = '\n';
++i;
}
s[i] = '\0';
return i;
}
复制功能:
/*copy: copy `from` into `to`; assume to is big enough*/
void copy(char to[], char from[]) {
int i;
i = 0;
while ((to[i] = from[i]) != '\0') {
++i;
}
}
答案 0 :(得分:2)
当getline
到达i
或从文件读取的下一个字节是9
时,'\n'
函数会停止。您不能在循环结束时同时使用这两个条件,因此仅当'\n'
小于i
时才会添加9
,因此永远不会将无效位置s[10]
存储到
假设输入文件包含字节:
+---+---+---+---+---+---+---+---+---+---+
| N | a | v | i | n | d | r | e | n |\n |
+---+---+---+---+---+---+---+---+---+---+
以下是getline()
执行的步骤:
i = 0
(循环初始化语句,执行一次)i < 9
- &gt;真c = getchar()
- &gt; c
收到'N'
c != EOF
- &gt;真c != '\n'
- &gt;真s[i] = c
- &gt; s[0]
收到'N'
i++
- &gt; i
现在是1
循环重复上述步骤,直到s[8]
收到'n'
,i
递增到9
。
最后的步骤是:
i < 9
- &gt; false,循环退出。if (c == '\n')
- &gt; false,c
包含'n'
,而非'\n'
,尚未读取换行符。跳过if
分支。s[i] = '\n'
- &gt; s[9]
收到空字节'\0'
。return i;
- &gt;值9
将返回给调用者。 getline()
的实现确实存在问题:您传递了目标数组大小的参数,但代码使用的是硬编码值MAXLINE
。
除此问题外,其行为与fgets()
非常相似。您是否打算这样做,或者您是否打算在没有尾随换行符的情况下读取该行,因为过去的不安全函数gets()
曾经这样做过?