我试图解开这段代码中的谜团,但徒劳无功。以下程序用于打印输入中的长度和行。它的 MAX 限制为 10 个字符,对于超过 10 个字符的行,它会计算所有字符,但仅存储 10 个字符。
让我感到困惑的是,在输出中,当一行超过 10 个字符的行作为输入时,当我将行存储在 10 个字符大小的数组中时,它会打印输入的前 11 个字符。怎么可能?
我在Linux Mint中使用GCC编译器。
#include<stdio.h>
#define MAX 10
int Getline(char arr[], int lim);
void main(){
int len=0;
char c=0;
char line[MAX]={};
len=Getline(line,MAX);
printf("%dn%s",len,line);
printf("nDo you want to continue?t");
while((c=getchar())=='y'){
len=Getline(line,MAX);
printf("n%dn%s",len,line);
printf("nDo you want to continue?t");
}
}
int Getline(char line[], int lim){
int i=0;
while((line[i]=getchar())!='n' && i<lim){
i++;
}
if(line[i]=='n' && i<lim)
{
line[i]=' '; // This is line[lim+1]
return i;
}
else if(i==lim){
while(getchar()!='n')
i++;
return i+1;
}
}
输入和输出如下所示,我在 linux mint 中使用 gcc 编译器。
输出:
Queen
5
Queen
Do you want to continue? yQueenOfDragons
14
QueenOfDrag
Do you want to continue? y123456789012345
15
12345678901
Do you want to continue? yYouKnowNothingJonSnow
21
YouKnowNoth
Do you want to continue? n
另外,当我在while循环中交换测试条件时,
如下所示while(i<lim && (line[i]=getchar())!='n')
当行长度超过限制时,它在打印前 10 个字符后打印一个奇怪的"@"字符。输出如下
产出2:
Queen
5
Queen
Do you want to continue? yQueenOfDragons
13
QueenOfDra@
Do you want to continue? y12345678901
10
1234567890@
Do you want to continue? yYouKnowNothingJonSnow
20
YouKnowNot@
Do you want to continue? n
请解释一下奇怪的行为。提前感谢!
PS:这是Dennis M Ritchie和Brian Kernighan的"C编程语言"中的练习1-16。
我怀疑它正在打印第 11 个字符,因为这个 而表达:
while((line[i]=getchar())!='n' && i<lim){
i++;
}
当i < lim
返回 false 时,您已经将getchar()
的结果放在line[i]
中。
此外,请记住始终使用 null 终止符为字符串留出空间并完成字符串。 Getline(line, lim)
并不总是将以 null 结尾的字符串放在 line
处
程序通过访问line[i]
在下一行调用长输入的未定义行为:
while((line[i]=getchar())!='n' && i<lim){
你可以在这里亲眼看到这一点。
由于line
指向大小lim
数组,因此您应该在写入line[i]
之前简单地测试是否i<lim
:
while(i<lim && (line[i]=getchar())!='n'){
修复该问题会在几行后显示相同的问题(链接(:
if(line[i]=='n' && i<lim)
修复此问题后,仍然存在一个问题,即您传递printf("%s",…
未以零结尾的字符数组的地址(链接(。
我对你的代码做了一些更改
#include<stdio.h>
#define MAX 10
int Getline(char arr[], int lim);
void main(){
int len=0;
char c=0;
char line[MAX]={};
len=Getline(line,MAX);
printf("%dn%s",len,line);
printf("nDo you want to continue?t");
while((c=getchar())=='y'){
len=Getline(line,MAX);
printf("n%dn%s",len,line);
printf("nDo you want to continue?t");
}
}
int Getline(char line[], int lim){
int i=0;
while((line[i]=getchar())!='n' && i<lim){
i++;
}
if(line[i]=='n' && i<lim)
{
line[i]=' '; // This is line[lim+1]
return i;
}
else if(i==lim){
line[lim] = ' '; //Change is being made here adding terminator to string
while(getchar()!='n')
i++;
return i+1;
}
}
解释: 在字符串中读取直到空指针,即"\0"。由于您在大小大于 10 的情况下以字符串形式声明它,因此它显示了这样的行为
尽管我建议声明大小为 max+1 的字符串,以便省略任何溢出的可能性
因为在大小为 10 的字符串中,应该有 9 个字符和 1 个空字符