非常奇怪的C异常 [英] VERY strange C anomaly
问题描述
请考虑以下摘录,附带相关的
声明。
首先,标有**,***,**的行**一开始不是
应该在开头有这些明星;他们只习惯直接关注
.
假设,首先,****的行不存在。
p_num以某种方式通过
sscanf命令(***)从之前的值变为0,甚至不涉及p_num。我不能理解它,我怎么可能做任何会修改其值的b / b
。标有**的行被添加以确定那是
确实是导致问题的行。 (之前的值为1,之后的值为0)。
然后我添加了标记为****的行以解决问题,但是是
这种廉价修复的理念非常糟糕的编程风格,
我想知道是否有人可以对此有所了解。
代码如下。
int main(int argc,char ** argv){
int pktsize,interval,numgums,p_pktsize,p_interval,p_num;
char trial,p_trial;
int wtf;
char buffer [200];
FILE * fp;
fp = fopen(argv [1], " r");
....
while(fgets(buffer,160,fp)!= NULL){
** printf(" p_numgums怎么突然变为0 =%d?!?!\ n",p_num);
**** wtf = p_num;
*** if(sscanf(缓冲区,%d%d%d%1s%* d%lf,& pktsize,
& interval,& numgums ,& trial,& commrate)== 5){
**** p_num = wtf;
** printf(ok,now what?% d \ n",p_num);
printf(" from the string |%s",buffer);
printf(" cur data set:pktsize = %d interval =%d num =%d trial =%c cmr =%f \ n",
pktsize,interval,numgums,trial,commrate);
printf(" prev data set:pktsize =%d interval =%d num = %d trial =%c cmr =%f \ n",
p_pktsize,p_interval,p_num,p_trial,p_commrate);
if(count = = -1){
count = 1; ++ j;
min = max = runtot = commrate;
}否则if((p_pktsize == pktsize)&&(p_interval ==
interval)&&(p_num == numgums)){
++ count; ++ j;
runtot + = commrate;
if(fcompare(commrate,min)< 0)min = commrate;
if (fcompare(max,commrate)< 0)max = commrate;
} else {
printf("%d \ t%d \ t%d) \t%c \%%d \ t%f \ t%f \ t%f \ n",
p_pktsize,p_interval,p_num,p_trial,count,
runtot / count,max,min);
count = 1; j = 1;
min = max = runtot = commrate;
}
p_pktsize = pktsize;
p_interval = interval;
printf(" numgums已从%d更改,p_num);
p_num = numgums;
printf("到%d \ n",p_num);
p_trial = trial;
p_commrate = commrate;
}
}
返回0;
}
我通过argv提供文件的头(-n10) [1]看起来像这样:
----
1000 10 1 a 10 91.041515 1500
1000 10 1 b 11 91.036757 1491
1000 10 1 c 12 87.535014 1500
1000 10 3 a 10 51.517332 859
1000 10 3 a 11 54.095827 910
1000 10 3 a 12 52.226982 890
1000 10 3 b 20 37.465007 629
1000 10 3 b 21 47.486709 786
1000 10 3 b 22 49.602106 829
1000 10 3 c 30 36.402570 629
----
非常困惑,
-Bernard Liang
Consider the following excerpt below, with the included relevant
declarations.
Firstly, the lines marked with **, ***, **** at the beginning are not
supposed to have those stars at the beginning; they are only used to
direct attention.
Suppose, first of all, that the lines with the **** are not present.
p_num is somehow getting changed from its previous value to 0 by the
sscanf command (***) that doesn''t even involve p_num. I cannot
understand it, how I could possibly be doing anything that would modify
its value. The lines marked ** were added to determine that that was
indeed the line causing the problem. (the value was 1 before, and 0 after).
I then added the lines marked **** to remedy the problem, but being of
the philosophy that such "cheap fixes" are very poor programming style,
I wanted to see if anyone could shed some insight on this.
Code follows.
int main(int argc, char** argv) {
int pktsize, interval, numgums, p_pktsize, p_interval, p_num;
char trial, p_trial;
int wtf;
char buffer[200];
FILE* fp;
fp = fopen(argv[1], "r");
....
while (fgets(buffer, 160, fp) != NULL) {
**printf("how did p_numgums suddenly change to 0=%d?!?!\n", p_num);
****wtf = p_num;
*** if (sscanf(buffer, "%d %d %d %1s %*d %lf", &pktsize,
&interval, &numgums, &trial, &commrate) == 5) {
****p_num = wtf;
**printf("ok, now what? %d\n", p_num);
printf("from the string |%s", buffer);
printf(" cur data set: pktsize=%d interval=%d num=%d trial=%c cmr=%f\n",
pktsize, interval, numgums, trial, commrate);
printf("prev data set: pktsize=%d interval=%d num=%d trial=%c cmr=%f\n",
p_pktsize, p_interval, p_num, p_trial, p_commrate);
if (count == -1) {
count = 1; ++j;
min = max = runtot = commrate;
} else if ((p_pktsize == pktsize) && (p_interval ==
interval) && (p_num == numgums)) {
++count; ++j;
runtot += commrate;
if (fcompare(commrate, min) < 0) min = commrate;
if (fcompare(max, commrate) < 0) max = commrate;
} else {
printf("%d\t%d\t%d\t%c\t%d\t%f\t%f\t%f\n",
p_pktsize, p_interval, p_num, p_trial, count,
runtot / count, max, min);
count = 1; j = 1;
min = max = runtot = commrate;
}
p_pktsize = pktsize;
p_interval = interval;
printf("numgums was changed from %d", p_num);
p_num = numgums;
printf("to %d\n", p_num);
p_trial = trial;
p_commrate = commrate;
}
}
return 0;
}
The head (-n10) of the file I am feeding it via argv[1] looks likes this:
----
1000 10 1 a 10 91.041515 1500
1000 10 1 b 11 91.036757 1491
1000 10 1 c 12 87.535014 1500
1000 10 3 a 10 51.517332 859
1000 10 3 a 11 54.095827 910
1000 10 3 a 12 52.226982 890
1000 10 3 b 20 37.465007 629
1000 10 3 b 21 47.486709 786
1000 10 3 b 22 49.602106 829
1000 10 3 c 30 36.402570 629
----
Extremely confused,
-Bernard Liang
推荐答案
如果你发布了你正在编译的实际来源(而不是一些片段)你可以得到一个更合理的答案。
例如,commrate未定义,但类型信息对于
至关重要,看看你是否通过糟糕的sscanf()格式说明符覆盖了某些东西。
If you post the actual source you are compiling (and not some fragments) you
can get a more reasonable answer.
For instance, commrate is not defined, but the type informationis crucial to
see if you are overwriting something via a bad sscanf() format specifier.
>
asdf,我以为我收录了所有内容。我猜不会。好吧,这是。
可能有一些不相关的decl''s b / c我正在修改另一个脚本
我写的。但是我认为这里没有什么实质性的东西在这里除了通信定义之外。
#include< stdio.h>
#include< math.h>
#include< float.h>
#include" gpslib。 h"
int main(int argc,char ** argv){
int pktsize,interval,numgums,p_pktsize,p_interval,p_num;
char trial,p_trial;
int wtf;
double commrate,p_commrate;
int count = 1 ,bufpos = 0,num,i,j; // count =#of gums
记录,bufpos = fgets缓冲区中的位置
double min = DBL_MAX,max = DBL_MIN,runtot = 0.0;
char buffer [200];
char * bufptr;
FILE * fp;
if( (argc!= 3)||((num = atoi(argv [2]))10)){
printf("%s [stat_file] [num(< = 10)] \ n",argv [0]);
返回1;
}
fp = fopen(argv [1]," r");
count = -1;
j = 0;
p_num = -1;
while(fgets(缓冲区,160,fp)!= NULL){
printf(f ***如何使p_numgums突然变为0 =%d? !?!\ n",p_num);
wtf = p_num;
sscanf(缓冲区,%d%d%d%1s%* d%lf ;,& pktsize,& interval,& numgums,
& trial,& commrate);
p_num = wtf;
printf(ok,now what?%d \ n,p_num);
printf(" from the string |%s",buffer);
的printf(QUOT; cur数据集:pktsize =%d interval =%d num =%d trial =%c cmr =%f \ n",
pktsize,interval,numgums,trial,commrate);
printf(" prev dataset:pktsize =%d interval =%d num =%d trial =%c cmr =%f \ n",
p_pktsize,p_interval,p_num ,p_trial,p_commrate);
if(count == -1){
count = 1; ++ j;
min = max = runtot = commrate;
}否则if((p_pktsize == pktsize)&&(p_interval == interval)& &
(p_num == numgums)&&(p_trial == trial)){
++ count; ++ j;
runtot + = commrate;
if(fcompare(commrate,min)< 0)min = commrate;
if (fcompare(max,commrate)< 0)max = commrate;
} else {
printf("%d \ t%d \ t%d) \t%c \%%d \ t%f \ t%f \ t%f \ n",
p_pktsize,p_interval,p_num,p_trial,count,runtot / count,max,
min);
count = 1; j = 1;
min = max = runtot = commrate;
}
p_pktsize = pktsize;
p_interval = interval;
printf(" numgums已从%d更改,p_num);
p_num = numgums;
printf("到%d \ n",p_num);
p_trial = trial;
p_commrate = commrate;
}
printf("%d \ t%d \ t%d \ t%\\ t \\ t%\\ t \\ t%\ t \\ t%f \ t%f \ t%f \ n" ;,p_pktsize,p_interval,p_num,
p_trial,count,runtot / count,max,min);
返回0;
}
Bernard Liang写道:
asdf, I thought I included everything. I guess not. Well here it is.
there might be some irrelevant decl''s b/c I was modifying another script
I had written. but I don''t think there''s anything substantial that is in
here other than the commrate defn''s.
#include <stdio.h>
#include <math.h>
#include <float.h>
#include "gpslib.h"
int main(int argc, char** argv) {
int pktsize, interval, numgums, p_pktsize, p_interval, p_num;
char trial, p_trial;
int wtf;
double commrate, p_commrate;
int count = 1, bufpos = 0, num, i, j; // count = # of gums
recorded, bufpos = position in fgets buffer
double min = DBL_MAX, max = DBL_MIN, runtot = 0.0;
char buffer[200];
char* bufptr;
FILE* fp;
if ((argc != 3) || ((num = atoi(argv[2])) 10)) {
printf("%s [stat_file] [num (<=10)]\n", argv[0]);
return 1;
}
fp = fopen(argv[1], "r");
count = -1;
j=0;
p_num = -1;
while (fgets(buffer, 160, fp) != NULL) {
printf("how the f*** did p_numgums suddenly change to 0=%d?!?!\n", p_num);
wtf = p_num;
sscanf(buffer, "%d %d %d %1s %*d %lf", &pktsize, &interval, &numgums,
&trial, &commrate);
p_num = wtf;
printf("ok, now what? %d\n", p_num);
printf("from the string |%s", buffer);
printf(" cur dataset: pktsize=%d interval=%d num=%d trial=%c cmr=%f\n",
pktsize, interval, numgums, trial, commrate);
printf("prev dataset: pktsize=%d interval=%d num=%d trial=%c cmr=%f\n",
p_pktsize, p_interval, p_num, p_trial, p_commrate);
if (count == -1) {
count = 1; ++j;
min = max = runtot = commrate;
} else if ((p_pktsize == pktsize) && (p_interval == interval) &&
(p_num == numgums) && (p_trial == trial)) {
++count; ++j;
runtot += commrate;
if (fcompare(commrate, min) < 0) min = commrate;
if (fcompare(max, commrate) < 0) max = commrate;
} else {
printf("%d\t%d\t%d\t%c\t%d\t%f\t%f\t%f\n",
p_pktsize, p_interval, p_num, p_trial, count, runtot / count, max,
min);
count = 1; j = 1;
min = max = runtot = commrate;
}
p_pktsize = pktsize;
p_interval = interval;
printf("numgums was changed from %d", p_num);
p_num = numgums;
printf("to %d\n", p_num);
p_trial = trial;
p_commrate = commrate;
}
printf("%d\t%d\t%d\t%c\t%d\t%f\t%f\t%f\n", p_pktsize, p_interval, p_num,
p_trial, count, runtot / count, max, min);
return 0;
}
Bernard Liang wrote:
请考虑以下摘录,附带相关的
声明。
首先,开头标有**,***,****的行不是
应该有的那些明星一开始;他们只习惯直接关注
.
假设,首先,****的行不存在。
p_num以某种方式通过
sscanf命令(***)从之前的值变为0,甚至不涉及p_num。我不能理解它,我怎么可能做任何会修改其值的b / b
。标有**的行被添加以确定那是
确实是导致问题的行。 (之前的值为1,之后的值为0)。
然后我添加了标记为****的行以解决问题,但是是
这种廉价修复的理念非常糟糕的编程风格,
我想知道是否有人可以对此有所了解。
代码如下。
int main(int argc,char ** argv){
int pktsize,interval,numgums,p_pktsize,p_interval,p_num;
char trial,p_trial;
int wtf;
char buffer [200];
FILE * fp;
fp = fopen(argv [1],r);
...
while(fgets(buffer,160,fp)!= NULL){
** printf(" p_numgums怎么突然变为0 =%d?!?!\ n",p_num);
**** wtf = p_num;
*** if(sscanf(缓冲区,%d%d%d%1s%* d%lf,& pktsize,
& interval, & numgums,& trial,& commrate)== 5){
**** p_num = wtf;
** printf(" ok,now什么?%d \ n",p_num);
printf(" from the string |%s",buffer);
printf(" cur data set :pktsize =%d interval =%d num =%d trial =%c cmr =%f \ n",
pktsize,interval,numgums,trial,commrate);
printf(" prev data set:pktsize =%d interval =%d num =%d trial =%c cmr =%f \ n",
p_pktsize,p_interval,p_num,p_trial,p_commrate);
if(count == -1){
count = 1; ++ j;
min = max = runtot = commrate;
}否则if((p_pktsize == pktsize)&&(p_interval ==
interval)&&(p_num == numgums)){
++ count; ++ j;
runtot + = commrate;
if(fcompare(commrate,min)< 0)min = commrate;
if (fcompare(max,commrate)< 0)max = commrate;
} else {
printf("%d \ t%d \ t%d) \t%c \%%d \ t%f \ t%f \ t%f \ n",
p_pktsize,p_interval,p_num,p_trial,count,runtot
/ count,max,min);
count = 1; j = 1;
min = max = runtot = commrate;
}
p_pktsize = pktsize;
p_interval = interval;
printf(" numgums已从%d更改,p_num);
p_num = numgums;
printf("到%d \ n",p_num);
p_trial = trial;
p_commrate = commrate;
}
}
返回0;
}
我通过argv提供文件的头(-n10) [1]看起来像这样:
----
1000 10 1 a 10 91.041515 1500
1000 10 1 b 11 91.036757 1491
1000 10 1 c 12 87.535014 1500
1000 10 3 a 10 51.517332 859
1000 10 3 a 11 54.095827 910
1000 10 3 a 12 52.226982 890
1000 10 3 b 20 37.465007 629
1000 10 3 b 21 47.486709 786
1000 10 3 b 22 49.602106 829 < br $>
1000 10 3 c 30 36.402570 629
----
非常困惑,
- Bernard Liang
Consider the following excerpt below, with the included relevant
declarations.
Firstly, the lines marked with **, ***, **** at the beginning are not
supposed to have those stars at the beginning; they are only used to
direct attention.
Suppose, first of all, that the lines with the **** are not present.
p_num is somehow getting changed from its previous value to 0 by the
sscanf command (***) that doesn''t even involve p_num. I cannot
understand it, how I could possibly be doing anything that would modify
its value. The lines marked ** were added to determine that that was
indeed the line causing the problem. (the value was 1 before, and 0 after).
I then added the lines marked **** to remedy the problem, but being of
the philosophy that such "cheap fixes" are very poor programming style,
I wanted to see if anyone could shed some insight on this.
Code follows.
int main(int argc, char** argv) {
int pktsize, interval, numgums, p_pktsize, p_interval, p_num;
char trial, p_trial;
int wtf;
char buffer[200];
FILE* fp;
fp = fopen(argv[1], "r");
...
while (fgets(buffer, 160, fp) != NULL) {
**printf("how did p_numgums suddenly change to 0=%d?!?!\n", p_num);
****wtf = p_num;
*** if (sscanf(buffer, "%d %d %d %1s %*d %lf", &pktsize,
&interval, &numgums, &trial, &commrate) == 5) {
****p_num = wtf;
**printf("ok, now what? %d\n", p_num);
printf("from the string |%s", buffer);
printf(" cur data set: pktsize=%d interval=%d num=%d trial=%c cmr=%f\n",
pktsize, interval, numgums, trial, commrate);
printf("prev data set: pktsize=%d interval=%d num=%d trial=%c cmr=%f\n",
p_pktsize, p_interval, p_num, p_trial, p_commrate);
if (count == -1) {
count = 1; ++j;
min = max = runtot = commrate;
} else if ((p_pktsize == pktsize) && (p_interval ==
interval) && (p_num == numgums)) {
++count; ++j;
runtot += commrate;
if (fcompare(commrate, min) < 0) min = commrate;
if (fcompare(max, commrate) < 0) max = commrate;
} else {
printf("%d\t%d\t%d\t%c\t%d\t%f\t%f\t%f\n",
p_pktsize, p_interval, p_num, p_trial, count, runtot
/ count, max, min);
count = 1; j = 1;
min = max = runtot = commrate;
}
p_pktsize = pktsize;
p_interval = interval;
printf("numgums was changed from %d", p_num);
p_num = numgums;
printf("to %d\n", p_num);
p_trial = trial;
p_commrate = commrate;
}
}
return 0;
}
The head (-n10) of the file I am feeding it via argv[1] looks likes this:
----
1000 10 1 a 10 91.041515 1500
1000 10 1 b 11 91.036757 1491
1000 10 1 c 12 87.535014 1500
1000 10 3 a 10 51.517332 859
1000 10 3 a 11 54.095827 910
1000 10 3 a 12 52.226982 890
1000 10 3 b 20 37.465007 629
1000 10 3 b 21 47.486709 786
1000 10 3 b 22 49.602106 829
1000 10 3 c 30 36.402570 629
----
Extremely confused,
-Bernard Liang
Bernard Liang< b _ ***** @ berkeley.eduwrites:
Bernard Liang <b_*****@berkeley.eduwrites:
int pktsize,interval,numgums,p_pktsize,p_interval,p_num;
char trial,p_trial;
int pktsize, interval, numgums, p_pktsize, p_interval, p_num;
char trial, p_trial;
[...]
[...]
*** if(sscanf(buffer,"%d) %d%d%1s%* d%lf",& pktsize,
& interval,& numgums,& trial,& commrate)== 5){
*** if (sscanf(buffer, "%d %d %d %1s %*d %lf", &pktsize,
&interval, &numgums, &trial, &commrate) == 5) {
%1s将存储一个非空格字符和一个终止
%1s或者将试验声明为2个字符的数组。
你没有显示通信声明。它应该有类型
double。
-
有些人*是*傲慢,其他人阅读常见问题解答。
--Chris Dollin
%1s will store one non-white space character plus a terminating
null, but you only allocated room for one byte. Use %c instead
of %1s or declare trial as an array of 2 characters instead.
You didn''t show the declaration of commrate. It should have type
double.
--
"Some people *are* arrogant, and others read the FAQ."
--Chris Dollin
这篇关于非常奇怪的C异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!