测测你是否细心,一段蒙了2个老板的代码^_^

dotmonkey 2009-08-01 07:28:07
嗯,先别看回贴,你看得出bug在哪吗?呵呵,一个小小的bug导致我加班一晚上没找出来,
2个老板亲自找也没找着bug在哪哦^_^

#include <stdio.h>
/*
* 功能说明:解析NMEA语句中的GPGSA语句,提取第2,15,16,17个字段。
* 字段以','分开,并且字段有可能为空。
*/
static char *gsa = "$GPGSA,A,3,19,28,14,18,27,22,31,39,,,,,1.7,1.0,1.3*34";

int main(int argc,char* argv[])
{
int field = 0;
int i;
int loc;
float pdop,hdop,vdop;

for(i = 0; (gsa[i] != 0) && (gsa[i]!='*'); i++){/* '*' 或空格为结束符 */
if(gsa[i]==',') field++;/*当前字段*/
switch(field){
case 2:
sscanf(gsa + i + 1, "%d", &loc);/*从','下一字符开始sscanf*/
break;
case 15:
sscanf(gsa + i + 1, "%f", &pdop);
break;
case 16:
sscanf(gsa + i + 1, "%f", &hdop);
break;
case 17:
sscanf(gsa + i + 1, "%f", &vdop);
break;
default:
break;
}
}
printf("loc = %d, pdop = %2.1f, hdop = %2.1f, vdop = %2.1f\n",
loc, pdop, hdop, vdop);
return 0;
}

...全文
410 28 打赏 收藏 转发到动态 举报
写回复
用AI写文章
28 条回复
切换为时间正序
请发表友善的回复…
发表回复
dzq138 2009-11-09
  • 打赏
  • 举报
回复
支持单步调试

一开始就是想着单步调试.可能比你想一天要好...
HelloDan 2009-08-02
  • 打赏
  • 举报
回复
收着下次看吧。
f22fbi 2009-08-02
  • 打赏
  • 举报
回复
[Quote=引用 20 楼 ltc_mouse 的回复:]
现在提取出来的这段代码就很容易进行单步调试呀,^_^

我的意思是,当定位到问题发生在某个局部内,或者某个函数,完全可以简单移植到PC中,进行单步调试,效率相对而言会高很多吧~
[/Quote]
支持单步调试
mu_yang 2009-08-01
  • 打赏
  • 举报
回复
if(gsa[i]==',') field++;/*当前字段*/
应该是
if(gsa[i]==',') field++;/*当前字段*/
else continue ;



一定要用for么?
用两个指针标记字段的头尾
用while或do-while更自然吧
ltc_mouse 2009-08-01
  • 打赏
  • 举报
回复
现在提取出来的这段代码就很容易进行单步调试呀,^_^

我的意思是,当定位到问题发生在某个局部内,或者某个函数,完全可以简单移植到PC中,进行单步调试,效率相对而言会高很多吧~
dotmonkey 2009-08-01
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 ltc_mouse 的回复:]
不知道楼主有没用单步调试? 发现问题应该不难~~

当然,当局者迷,有时候就会这样,一个很小的问题,花了很久找出来,然后回头笑自己,:)
至于*,个人认为strchr,strtok等都能定位,自己写循环确实一定程度增加了Bug产生的几率,呵呵
[/Quote]
小公司,一个人整的项目,不完善,没办法单部,呵呵。
strchr等可以定位没错,但是效率上还是循环的方法高一些。
ltc_mouse 2009-08-01
  • 打赏
  • 举报
回复
不知道楼主有没用单步调试? 发现问题应该不难~~

当然,当局者迷,有时候就会这样,一个很小的问题,花了很久找出来,然后回头笑自己,:)
至于*,个人认为strchr,strtok等都能定位,自己写循环确实一定程度增加了Bug产生的几率,呵呵
lijian22500 2009-08-01
  • 打赏
  • 举报
回复
我也在做GPS数据解析,参考了楼主的解析方法,收益了。
lijian22500 2009-08-01
  • 打赏
  • 举报
回复
#include <stdio.h>
/*
* 功能说明:解析NMEA语句中的GPGSA语句,提取第2,15,16,17个字段。
* 字段以','分开,并且字段有可能为空。
*/
static char *gsa = "$GPGSA,A,3,19,28,14,18,27,22,31,39,,,,,1.7,1.0,1.3*34";

int main(int argc,char* argv[])
{
int field = 0;
int i;
int loc;
float pdop,hdop,vdop;

for(i = 0; (gsa[i] != 0) && (gsa[i]!='*'); i++){/* '*' 或空格为结束符 */
if(gsa[i]==',')
{
field++;/*当前字段*/
switch(field){
case 2:
sscanf(gsa + i + 1, "%d", &loc);/*从','下一字符开始sscanf*/
break;
case 15:
sscanf(gsa + i + 1, "%f", &pdop);
break;
case 16:
sscanf(gsa + i + 1, "%f", &hdop);
break;
case 17:
sscanf(gsa + i + 1, "%f", &vdop);
break;
default:
break;
}
}
}
printf("loc = %d, pdop = %2.1f, hdop = %2.1f, vdop = %2.1f\n",
loc, pdop, hdop, vdop);
return 0;
}


把switch加到if模块里面。
dotmonkey 2009-08-01
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 haierpro 的回复:]
解决方法嘛,参考5楼的,再加了些改进:

C/C++ code
#include<stdio.h>/*
* 功能说明:解析NMEA语句中的GPGSA语句,提取第2,15,16,17个字段。
* 字段以','分开,并且字段有可能为空。*/staticchar*gsa="$GPGSA,A,3,19,28,14,18,27,22,31,39,,,,,1.7,1.0,1.3*34";int main(int argc,char* argv[])
{int field=0;int i;int loc;float pdop,hdop,vdop;for(i=0; (gsa[i]!=0)&& (gsa[i]!='*'); i++)/* '*' 或空格为结束符*/
{if(gsa[i]==',')
{
field++;/*当前字段*/
}else
{continue;
}switch(field)
{case2:if (gsa[i+1]!=',')
{
sscanf(gsa+ i+1,"%d",&loc);/*从','下一字符开始sscanf*/
}else
{
loc=0;//loc置无效标志 }break;case15:if (gsa[i+1]!=',')
{
sscanf(gsa+ i+1,"%f",&pdop);
}else
{
pdop=0;//pdop置无效标志 }break;case16:if (gsa[i+1]!=',')
{
sscanf(gsa+ i+1,"%f",&hdop);
}else
{
hdop=0;//hdop置无效标志 }break;case17:if (gsa[i+1]!=',')
{
sscanf(gsa+ i+1,"%f",&vdop);
}else
{
vdop=0;//vdop置无效标志 }break;default:break;

}
}
printf("loc = %d, pdop = %2.1f, hdop = %2.1f, vdop = %2.1f\n",
loc, pdop, hdop, vdop);return0;
}
[/Quote]
要的不是解决方法,解决方法加一对大括号就行了,呵呵
要的是找到bug的方法。
dotmonkey 2009-08-01
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 freshow 的回复:]
这种编程规范很烂的代码~出问题找不出来也很正常
[/Quote]
我想你应该很少接触开源的代码吧?呵呵
每个人的风格或者喜好是不一样的
haierpro 2009-08-01
  • 打赏
  • 举报
回复
解决方法嘛,参考5楼的,再加了些改进:


#include <stdio.h>
/*
* 功能说明:解析NMEA语句中的GPGSA语句,提取第2,15,16,17个字段。
* 字段以','分开,并且字段有可能为空。
*/
static char *gsa = "$GPGSA,A,3,19,28,14,18,27,22,31,39,,,,,1.7,1.0,1.3*34";

int main(int argc,char* argv[])
{
int field = 0;
int i;
int loc;
float pdop,hdop,vdop;

for(i = 0; (gsa[i] != 0) && (gsa[i]!='*'); i++) /* '*' 或空格为结束符 */
{
if(gsa[i]==',')
{
field++; /*当前字段*/
}
else
{
continue;
}

switch(field)
{
case 2:
if (gsa[i+1] != ',')
{
sscanf(gsa + i + 1, "%d", &loc);/*从','下一字符开始sscanf*/
}
else
{
loc = 0; //loc置无效标志
}
break;
case 15:
if (gsa[i+1] != ',')
{
sscanf(gsa + i + 1, "%f", &pdop);
}
else
{
pdop = 0; //pdop置无效标志
}
break;
case 16:
if (gsa[i+1] != ',')
{
sscanf(gsa + i + 1, "%f", &hdop);
}
else
{
hdop = 0; //hdop置无效标志
}
break;
case 17:
if (gsa[i+1] != ',')
{
sscanf(gsa + i + 1, "%f", &vdop);
}
else
{
vdop = 0; //vdop置无效标志
}
break;
default:
break;

}
}
printf("loc = %d, pdop = %2.1f, hdop = %2.1f, vdop = %2.1f\n",
loc, pdop, hdop, vdop);
return 0;
}


freshow 2009-08-01
  • 打赏
  • 举报
回复
这种编程规范很烂的代码~出问题找不出来也很正常
dotmonkey 2009-08-01
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 delphinew 的回复:]
这充分说明,
闭门造车是不好的,如果你的source open一些,bug很快就可以找到,设计也可以改进~

C/C++ code
#include<stdio.h>
#include<string.h>/*
* 功能说明:解析NMEA语句中的GPGSA语句,提取第2,15,16,17个字段。
* 字段以','分开,并且字段有可能为空。*/staticchar*gsa="$GPGSA,A,3,19,28,14,18,27,22,31,39,,,,,1.7,1.0,1.3*34";int main(int argc,char* argv[])
{int field=0;int i;int loc;float pdop,hdop,vdop;/******************** BETTER SOLUTION*/#define MAX_GSA 256char*iter= gsa;for(iter= strchr(iter,','); iter; iter= strchr(iter,',')) {if (*iter)++iter;++field;if (field==2)
sscanf(iter,"%d",&loc);if (field==15)
sscanf(iter,"%f",&pdop);if (field==16)
sscanf(iter,"%f",&hdop);if (field==17)
sscanf(iter,"%f",&vdop);
}
printf("loc = %d, pdop = %2.1f, hdop = %2.1f, vdop = %2.1f\n",
loc, pdop, hdop, vdop);/******************** BETTER SOLUTION*/for(i=0; (gsa[i]!=0)&& (gsa[i]!='*'); i++){/* '*' 或空格为结束符*/if (gsa[i]==',')
field++;/*当前字段*/switch(field){case2:
sscanf(gsa+ i+1,"%d",&loc);/*从','下一字符开始sscanf*/break;case15:
printf(gsa+ i+1);/*这两句可以帮忙发现bug*/
printf("---field: %d\n", field);/*同一field不该多次出现*/
sscanf(gsa+ i+1,"%f",&pdop);while (gsa[i+1]&& gsa[i+1]!=',')/*hack fix*/++i;break;case16:
printf(gsa+ i+1);
printf("---field: %d\n", field);
sscanf(gsa+ i+1,"%f",&hdop);while (gsa[i+1]&& gsa[i+1]!=',')++i;break;case17:
printf(gsa+ i+1);
printf("---field: %d\n", field);
sscanf(gsa+ i+1,"%f",&vdop);while (gsa[i+1]&& gsa[i+1]!=',')++i;break;default:break;
}
}
printf("loc = %d, pdop = %2.1f, hdop = %2.1f, vdop = %2.1f\n",
loc, pdop, hdop, vdop);return0;
}
[/Quote]

毕竟是公司的东西不能随便open,你的BETTER SOLUTION 并不better ^_^,看上去strsep更符合语义,但是你也忘了'*',呵呵
找出来的都谈谈方法吧:)
dotmonkey 2009-08-01
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 rendao0563 的回复:]
发个C++的。
C/C++ code
#include<string>
#include<vector>
#include<stdio.h>usingnamespace std;/*
* 功能说明:解析NMEA语句中的GPGSA语句,提取第2,15,16,17个字段。
* 字段以','分开,并且字段有可能为空。*/staticchar*gsa="$GPGSA,A,3,19,28,14,18,27,22,31,39,,,,,1.7,1.0,1.3*34";

vector<string> ExtractStrings(string sSource,char delim,bool bEnableEmpty);int main(int argc,char* argv[])
{
vector<string> vecGSA= ExtractStrings(gsa,',',true);

printf("loc = %d, pdop = %2.1f, hdop = %2.1f, vdop = %2.1f\n",
atoi(vecGSA[2].c_str()), atof(vecGSA[15].c_str()), atof(vecGSA[16].c_str()), atof(vecGSA[17].c_str()));return0;
}///////////////////////////////////////////////////////////////////////////// [UT]分割字符串/// 位于字符串末尾的分割符总是被忽略/// @param sSource 待分割的字符串/// @param delim 分割字符/// @param bEnableEmpty 是否允许空字符串,如果该参数设为true,则相连的两个/// 分隔符之间认为存在一个空串(该参数默认值为false)/// @return 字符串列表//////////////////////////////////////////////////////////////////////////vector<string> ExtractStrings(string sSource,char delim,bool bEnableEmpty=false)
{string::size_type pos1, pos2;
vector<string> strParams;
pos2=0;while (pos2!=string::npos)
{if (bEnableEmpty)
{if (sSource[pos2]== delim)
{
pos2+=1;
strParams.push_back("");continue;
}
}

pos1= sSource.find_first_not_of(delim, pos2);if (pos1==string::npos)break;
pos2= sSource.find_first_of(delim, pos1+1);if (pos2==string::npos)
{if (pos1!= sSource.size())
strParams.push_back(sSource.substr(pos1));break;
}
strParams.push_back(sSource.substr(pos1, pos2- pos1));

pos2+=1;
}return strParams;
}
[/Quote]

前面的回复对了,这个让你给引入新bug了,'*'也是结束符。
dotmonkey 2009-08-01
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 haierpro 的回复:]
还有, 在 field自加之前,一个字段会读取多次,最终只取得了要读取的字段的最后一个字符
[/Quote]
不错,怎么找着的?有好的办法?
空格只是口误,原意是空字符,就是0.
zjf30366 2009-08-01
  • 打赏
  • 举报
回复
en
JoyerHuang_悦 2009-08-01
  • 打赏
  • 举报
回复
这充分说明,
闭门造车是不好的,如果你的source open一些,bug很快就可以找到,设计也可以改进~


#include <stdio.h>
#include <string.h>
/*
* 功能说明:解析NMEA语句中的GPGSA语句,提取第2,15,16,17个字段。
* 字段以','分开,并且字段有可能为空。
*/
static char *gsa = "$GPGSA,A,3,19,28,14,18,27,22,31,39,,,,,1.7,1.0,1.3*34";

int main(int argc,char* argv[])
{
int field = 0;
int i;
int loc;
float pdop,hdop,vdop;
/******************** BETTER SOLUTION */
#define MAX_GSA 256
char *iter = gsa;
for(iter = strchr(iter, ','); iter; iter = strchr(iter, ',')) {
if (*iter)
++iter;
++field;
if (field == 2)
sscanf(iter, "%d", &loc);
if (field == 15)
sscanf(iter, "%f", &pdop);
if (field == 16)
sscanf(iter, "%f", &hdop);
if (field == 17)
sscanf(iter, "%f", &vdop);
}
printf("loc = %d, pdop = %2.1f, hdop = %2.1f, vdop = %2.1f\n",
loc, pdop, hdop, vdop);
/******************** BETTER SOLUTION */

for(i = 0; (gsa[i] != 0) && (gsa[i]!='*'); i++){/* '*' 或空格为结束符 */
if (gsa[i]==',')
field++;/*当前字段*/
switch(field){
case 2:
sscanf(gsa + i + 1, "%d", &loc);/*从','下一字符开始sscanf*/
break;
case 15:
printf(gsa + i + 1); /*这两句可以帮忙发现bug*/
printf("---field: %d\n", field); /*同一field不该多次出现*/
sscanf(gsa + i + 1, "%f", &pdop);
while (gsa[i+1] && gsa[i+1] != ',') /*hack fix*/
++i;
break;
case 16:
printf(gsa + i + 1);
printf("---field: %d\n", field);
sscanf(gsa + i + 1, "%f", &hdop);
while (gsa[i+1] && gsa[i+1] != ',')
++i;
break;
case 17:
printf(gsa + i + 1);
printf("---field: %d\n", field);
sscanf(gsa + i + 1, "%f", &vdop);
while (gsa[i+1] && gsa[i+1] != ',')
++i;
break;
default:
break;
}
}
printf("loc = %d, pdop = %2.1f, hdop = %2.1f, vdop = %2.1f\n",
loc, pdop, hdop, vdop);


return 0;
}

rendao0563 2009-08-01
  • 打赏
  • 举报
回复
发个C++的。

#include<string>
#include<vector>
#include <stdio.h>
using namespace std;
/*
* 功能说明:解析NMEA语句中的GPGSA语句,提取第2,15,16,17个字段。
* 字段以','分开,并且字段有可能为空。
*/

static char *gsa = "$GPGSA,A,3,19,28,14,18,27,22,31,39,,,,,1.7,1.0,1.3*34";

vector<string> ExtractStrings(string sSource, char delim, bool bEnableEmpty);

int main(int argc,char* argv[])
{
vector<string> vecGSA = ExtractStrings(gsa,',',true);

printf("loc = %d, pdop = %2.1f, hdop = %2.1f, vdop = %2.1f\n",
atoi(vecGSA[2].c_str()), atof(vecGSA[15].c_str()), atof(vecGSA[16].c_str()), atof(vecGSA[17].c_str()));
return 0;
}

//////////////////////////////////////////////////////////////////////////
/// [UT]分割字符串
/// 位于字符串末尾的分割符总是被忽略
/// @param sSource 待分割的字符串
/// @param delim 分割字符
/// @param bEnableEmpty 是否允许空字符串,如果该参数设为true,则相连的两个
/// 分隔符之间认为存在一个空串(该参数默认值为false)
/// @return 字符串列表
//////////////////////////////////////////////////////////////////////////
vector<string> ExtractStrings(string sSource, char delim, bool bEnableEmpty = false)
{
string::size_type pos1, pos2;
vector<string> strParams;
pos2 = 0;
while (pos2 != string::npos)
{
if (bEnableEmpty)
{
if (sSource[pos2] == delim)
{
pos2 += 1;
strParams.push_back("");
continue;
}
}

pos1 = sSource.find_first_not_of(delim, pos2);
if (pos1 == string::npos)
break;
pos2 = sSource.find_first_of(delim, pos1 + 1);
if (pos2 == string::npos)
{
if (pos1 != sSource.size())
strParams.push_back(sSource.substr(pos1));
break;
}
strParams.push_back(sSource.substr(pos1, pos2 - pos1));

pos2 += 1;
}
return strParams;
}
rendao0563 2009-08-01
  • 打赏
  • 举报
回复

if(gsa[i] == ',')
{
field++;/*当前字段*/
}
else
{
continue;
}
加载更多回复(7)

15,440

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 非技术区
社区管理员
  • 非技术区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧