昨天,我在代码厨师中解决了一个名为At The Gates的问题。我用C语言编写了一些没有语法错误的代码,因为该代码的编译过程中警告和错误为零。
该代码在第一个测试用例上运行正常,但是在第二个测试中给出了分段错误错误。
当我调试它时,它表明分段错误是由于代码行造成的
if(a[N-1]=='H');
调试器输出:
程序收到信号SIGSEGV,分段错误。 main.c中main()中的0x00000000004006d4:15
请帮助我纠正和更正代码。
#include<stdio.h>
void main(){
int T;
scanf("%d",&T);
while(T!=0){
int N=0,K,count=0,i;
scanf("%d%d",&N,&K);
char a[200];
for(i=0;i<N;i++){
scanf("%c",&a[i]);
}
while(K--){
if(a[N-1]=='H'){
N--;
for(i=0;i<N;i++){
if(a[i]=='H'){
a[i]=='T';
}
if(a[i]=='T'){
a[i]=='H';
}
}
}
else{
N--;
}
}
for(i=0;i<N;i++){
if(a[i]=='H'){
count=count+1;
}
}
printf("%d\n",count);
T=T-1;
}
}
答案 0 :(得分:1)
连同评论中提到的其他建议-
main
签名以返回int
a[i]=='T';
和a[i]=='H';
以删除if
块内的double equals警告(用==
替换=
在逻辑上是不正确的,请参阅@CiaPan的答案下面)您还必须更新scanf
语句
-scanf("%c",&a[i]);
至scanf(" %c",&a[i]);
(请注意%c
之前的多余空格)
这应该可以解决细分错误问题。
%d
自动吃掉空格和特殊字符,因为空格和特殊字符是字符,而不是数字!但是,%c
必须将空格和特殊字符解释为输入,因为%c
会读取字符。
说明-
在如下所示的程序中添加一些printf语句以检查收到的输入时,我们可以看到会发生什么情况-
int N=0,K,count=0,i; // N initialized to 0, but not K
printf("Before scan N=%d, K=%d\n", N, K);
i=scanf("%d%d",&N,&K);
char a[200];
printf("After scan-\n N=%d, K=%d, Scanf return value=%d\n", N, K, i);
for(i=0;i<N;i++){
scanf("%c",&a[i]);
}
for(i=0;i<N;i++){
printf("%d=>'%c', ",i, a[i]);
}
printf("\n");
有输入-
3
5 3
H T T H T
7 4
H H T T T H H
6 1
T H T H T T
整个程序的输出看起来像这样-
Before scan N=0, K=1362879360
After scan-
N=5, K=3, Scanf return value=2 <------ 2 VALUES SUCCESSFULLY READ
0=>'
', 1=>'H', 2=>' ', 3=>'T', 4=>' ',
Program output - 1
Before scan N=0, K=-1
After scan-
N=0, K=-1, Scanf return value=0 <------ 0 VALUES SUCCESSFULLY READ (problem)
exited, segmentation fault
正如@CiaPan在评论中所提到的,%c
占用了数组中的每个字符,甚至空格和换行符,但部分输入行H T T H T
留在了输入缓冲区中。由于在第一个循环中N和K为正且N大于K,因此第二个while循环终止。
在主循环的第二次迭代(测试用例)期间,N初始化为0,而K在第一次循环迭代中的值为-1。由于无法将来自输入缓冲区的剩余数据正确分配给N和K,因此它们会继续使用该值。
现在进入第二个while循环(测试用例),K开始为负,因此条件while(K--)
在意外的长时间内保持正确(直到在整数边界处换行后K为零),并且N也保持递减。最终,对于较大的N负值,程序尝试访问不可访问的内存(使用a[N-1]
),从而导致分段错误。
通过确保N和K正确初始化并在整个程序中具有预期值,可以避免此问题。 scanf中%c
之前的空格将适当地消耗来自输入缓冲区的多余空格/换行符,以为数组提供正确的值,从而导致按预期从输入分配N,K个变量。可以通过检查return values of scanf函数来捕获此类输入问题。诸如K>0
之类的其他检查/断言可有助于调试。
答案 1 :(得分:0)
这段代码肯定不会 做您想要的事情:
object.method1();
.method2();
.method3();
// etc
说明
if(a[i]=='H'){
a[i]=='T';
}
if(a[i]=='T'){
a[i]=='H';
}
只是比较将数组项 a[i]=='T';
与常量a[i]
,但随后比较结果却没有任何作用– {{{ 1}}是否等于'T'
,不不会以任何方式影响程序的进一步执行。
如果将比较运算符a[i]
更改为赋值'T'
...
==
然后,该循环的每次执行将使=
数组{em>充满。你知道为什么吗?