useful tips about sscanf

大家可能都或多或少在C/C++语言中用过sscanf处理字符串,不过我倒用得不多,上次用这个函数还是半年前了。
这回有同事在用sscanf读取一串字符到一个结构体,以填充结构体的各个项,测试时发现sscanf会过滤掉开头的空白字符。
比如有如下结构体:
typedef struct tagT
{
char a[3+1];
char b[5+1];
char c[3+1];
} T;
还有如下字符串:
char *s = “01 2 “;
用如下方法读取:
T t;
memset(&t, 0×00, sizeof(T));
sscanf(s, “%3s%5s%3s”, &t.a, &t.b, &t.c);
printf(“a=/%s/\tb=/%s/\tc=/%s/\n”, t.a, t.b, t.c);
运行之后,会发现读入的字符串跟想像中的不一样:
a=/01/ b=/2/ c=//
而我想要的结果是:
a=/01 / b=/ / c=/ 2 /

这里的问题解决方法非常简单,只要把”%3s%5s%3s”中的s改成c即可,在sscanf中,%s是遇到非空格字符才开始读取的,直到读取到空格字符结束,而%c会把空格也读进来。

正确的解法是:
sscanf(s, “%3c%5c%3c”, &t.a, &t.b, &t.c);

而通过这个问题,发现了一个使用sscanf函数滤掉字符串首尾空格的方法,即sscanf(str, “%s”, str);

Leave a Comment

char, wchar_t & TCHAR

以前写程序都不太注意UNICODE问题,因为做的东西基本上都是在固定的平台上跑,而一般的函数用char传递字符串都没有问题。

这几天写程序遇到一个函数调用,居然只支持wchar_t的宽字符,就在程序里面写了不少wchar_t的字符串定义。写着写着就发现这样的代码太难看了,一会儿char,一会儿wchar_t的,乱。于是就返工,把他们都改成了TCHAR,并且定义了全局宏UNICODE(或者_UNICODE),这样一来,代码里面就都是TCHAR了。至于那些只支持UNICODE的函数,在编译的时候加入编译条件,如果没有定义UNICODE宏,就忽略他们吧。

相应的,有关字符串操作的函数,都改用了TCHAR.H里面定义的,比如strcpy改成了_tcscpy,sprintf改成了_stprintf

Leave a Comment

Fetch first record in Sybase, SQLServer and Oracle

今天用Sybase E/SQL C写一个数据库程序的时候,发现一个问题,如下语句:

EXEC SQL SELECT Field1, Field2 INTO :szField1, :szField2 FROM Table1;

如果结果返回多条语句时,会报错。

* SQLCODE=(-16843171)|
** SQL Server Error
** ct_results(): user api layer: external error: This routine cannot be called until all fetchable results have been completely processed.

因为多条记录不能放在一个:szField1变量里面。

那么怎么取第一条呢?

不同的数据库有不同的实现方法,Sybase可以这么做

> set rowcount 1
> select * from Table1
> set rowcount 0
> go

Oracle里面,我记得要简单点,可以这么写

> select * from Table1 where rownum=1

SQLServer里面,就最简单了,这么写

> select top 1 * from Table1

(记录一下,下次发现这样的错误,能迅速找到解药)

Leave a Comment

Basic usages of TinyXML

昨天根据TinyXML的docs,学习了一些基本的用法。TinyXML相对于Xerces来说,接口更加简洁,好理解。虽然MS XML Parser也不错,但对于需要跨平台部署的应用程序,是不适合的。

CString strMsg;
TiXmlDocument doc("demotest.xml");
bool loadOK = doc.LoadFile();
if (!loadOK)
strMsg.Format("Could not Load. [%s]\n", doc.ErrorDesc());
else
strMsg.Format("OK\n");
TiXmlHandle sectHandle(&doc);
// 修改第2个Item节点的TEXT值
sectHandle.ChildElement("ToDo", 0).ChildElement("Item", 1).Child(0).Text()->SetValue("Some Value");
// 修改的3个Item节点的distance属性
sectHandle.ChildElement("ToDo", 0).ChildElement("Item", 2).Element()->SetAttribute("distance", "so near");
// 修改第1个Item节点的名字
sectHandle.ChildElement("ToDo", 0).ChildElement("Item", 0).Element()->SetValue("Other Item");
// 取得第1个Item节点的TEXT值
strMsg.Format("%s", sectHandle.ChildElement("ToDo", 0).ChildElement("Other Item", 0).Element()->GetText());
// 取得第2个Item的节点名字
strMsg.Format("%s", sectHandle.ChildElement("ToDo", 0).ChildElement("Item", 1).Element()->Value());
// 取得第3个Item节点的distance属性
strMsg.Format("%s", sectHandle.ChildElement("ToDo", 0).ChildElement("Item", 2).Element()->Attribute("distance");
// 取得第3个Item节点的priority属性
int n=0;
sectHandle.ChildElement("ToDo", 0).ChildElement("Item", 2).Element()->Attribute("priority", &n);
AfxMessageBox(strMsg, MB_OK, 0);
doc.SaveFile();

XML文件的结构:

<?xml version=”1.0″ standalone=”no” ?>
<!– Our to do list data –>
<ToDo>
<!– Do I need a secure PDA? –>
<Item priority=”1″ distance=”close”>Go to the
<bold>Toy store!</bold>
</Item>
<Item priority=”2″ distance=”none”>test</Item>
<Item priority=”2″ distance=”far & back”>Look for Evil Dinosaurs!</Item>
</ToDo>

Leave a Comment

error LNK2001: unresolved external symbol ___argv

今天写一个小程序,在代码里面加了CxImage,链接的时候报错”error LNK2001: unresolved external symbol ___argv”,还有其他一堆外部符号,后来参考这个网页,加入了_AFXDLL符号,链接成功。

Leave a Comment

« Newer Posts · Older Posts »