自学内容网 自学内容网

C++学习笔记(29)

二十、统计字符串的字数
函数的原型:
// 统计字符串的字数,汉字、全角的符号算一个字,字母、数字、半角的符号也算一个字。
int sumwords(const char* str); 一个字符的取值围是 0-255。
ASCII 码为标准符号、数字、英文等进行了保留,取值范围是 0~127。
汉字用扩展 ASCII 码表示,取值范围是 128~255,常用的 16000 个汉字以双字节为主,不常用的
汉字可能使用 3 或 4 字节(甲骨文、战国时期各国的文字、不同版本的繁体字)。
本任务只考虑汉字是双字节的情况。
示例:
#define _CRT_SECURE_NO_WARNINGS // 使用 C 风格字符串操作的函数需要定义这个宏
#include <iostream>
using namespace std;
// 统计字符串的字数,全角的汉字、符号算一个字,半角的字母、数字、符号也算一个字。
int sumwords(const char* str)
{
if (str == 0) return -1; // 如果传进来的是空地址,直接返回,防止程序崩溃。
char* p = (char*)str; // 指向字符串的首地址,用于遍历。
int total = 0; // 统计的结果。
bool biswide = false; // 临时的标志位,标记是否已经有半个汉字了。
while (*p) // 遍历字符串。
{
if ((unsigned char) *p < 128) { // 如果是 ASCII 码标准字符,注意,当前字符一定要
转成 unsigned char。
total ++; // ASCII 码标准字符算一个字。
}
else { // 如果是 ASCII 码扩展字符,表示它
是半个汉字。
if (biswide == true) { // 如果已经有半个汉字了。
total++; // 加上当前半个汉字,刚好是一个字。
biswide = false; // 清空半个汉字的标志位。
}
else {
biswide = true; // 设置已存在半个汉字的标志位。
}
}
p++;
}
return total; // 返回统计结果。
}
int main()
{
cout << sumwords("我是一只 a 傻傻鸟。") << endl;
}
二十一、拆分字符串
字符串"aa,bb,cc,dd",中间用逗号分隔,把它拆分到字符串维数组中,拆分后有 4 个数据项,分别
是 "aa"、"bb"、"cc"、"dd"。
函数原型:
// str:目标串,需要拆分的字符串。
// splitstr:数据项的分隔字符串。
// values:一个字符串数组,用于存放拆分后的数据项。
// 返回拆分后数据项的个数。
size_t splitstr(const char* str, const char* splitstr, char values[][51]);
补充说明:C++提供了 strtok()库函数,用于拆分字符串。
char *strtok(char s[], const char *delim);
示例:
#define _CRT_SECURE_NO_WARNINGS // 使用 C 风格字符串操作的函数需要定义这个宏
#include <iostream>
using namespace std;
// 拆分字符串。
// str:目标串,需要拆分的字符串。
// splitstr:分隔符字符串。
// values:拆分后的结果存放的字符串数组。
size_t splitstr(const char* str, const char* splitstr, char values[][51])
//size_t splitstr(const char* str, const char* splitstr, char(*values)[51])
{
if (str == 0 || splitstr == 0) return 0; // 如果传进来的是空地址,直接返回,防止程序
崩溃。
size_t slen = strlen(splitstr); // 分隔符字符串的长度。
if (slen == 0) return 0; // 分隔符字符串为空没有任何意义。
size_t ii = 0; // values 数组中,有效数据项的个数。
char* p = (char*)str; // 待拆分内容的指针,初始化指向目标串的起始地址。
// aa,bb,cc,dd
// p p1 第一次循环。
// p p1 第二次循环。
// p p1 第三次循环。
// p 第四次循环。
while (true)
{
char* p1 = strstr(p, splitstr); // 查找分隔符的位置。
if (p1 != 0) { // 如果找到了分隔符。
strncpy(values[ii++], p, p1 - p); // 截取数据项的内容。
p = p1 + slen; // p 指向下一次待拆分字符串
的起始位置。
}
else { // 如果没有找到分隔符,一定是最后一个数据项。
strcpy(values[ii++], p); // 把最后一个数据项保存到数组中。
break;
}
}
return ii; // 返回有效数据项的个数。
}
int main()
{
char values[20][51];
memset(values, 0, sizeof(values));
// size_t fieldcount = splitstr("aa,bb,cc,dd", ",", values);
//size_t fieldcount = splitstr("aa,bb,cc,", ",", values);
//size_t fieldcount = splitstr(",,cc,", ",", values);
//size_t fieldcount = splitstr("cc", ",", values);
size_t fieldcount = splitstr("", ",", values);
for (size_t ii = 0; ii < fieldcount; ii++)
cout << "values[" << ii << "]=" << values[ii] << endl;
}
二十二、解析 xml 字符串
XML 可扩展标记语言(eXtensible Markup Language), 用于传输和存储数据。
例如:
<bh>3</bh><name>西施</name><sex>女</sex><age>18</age><yz>漂亮</yz>
以上 XML 包含了以下数据项:
1)bh 的值是 3;
2)name 的值是西施;
3)sex 的值是女;
4)age 的值是 18;
5)yz 的值是漂亮。
函数原型:
// 解析 xml 字符串。
// xmlbuffer:待解析的 xml 字符串。
// fieldname:字段名。
// value:字段的值。
// ilen:字段值的最大长度,超出 ilen 的内容将会被丢弃,缺省取值 0,表示不限长度。
// 返回值:如果 xmlbuffer 中存在 fieldname 的数据项,返回 true,否则返回 false。
// 注意,调用该函数的时候,必须保证 value 足够大,否则可能会造成内存泄漏。
// <bh>3</bh><name>西施</name><sex>女</sex><age>18</age><yz>漂亮</yz>
bool xmlbuffer(const char* xmlbuffer, const char* fieldname, char* value, const size_t ilen =
0);
char value[21]; // 用于存放字段的值。
xmlbuffer("<bh>3</bh><name>西施</name>","name",value);
cout << "value=" << value << endl; // 显示:value=西施
xmlbuffer("<bh>3</bh><name>西施</name>","name",value,2);
cout << "value=" << value << endl; // 显示:value=西
// 其它数据类型的重载函数。
bool xmlbuffer(const char* xmlbuffer, const char* fieldname, char& value);
bool xmlbuffer(const char* xmlbuffer, const char* fieldname, unsigned char& value);
bool xmlbuffer(const char* xmlbuffer, const char* fieldname, int& value);
bool xmlbuffer(const char* xmlbuffer, const char* fieldname, unsigned int& value);
bool xmlbuffer(const char* xmlbuffer, const char* fieldname, long& value);
bool xmlbuffer(const char* xmlbuffer, const char* fieldname, unsigned long& value);
bool xmlbuffer(const char* xmlbuffer, const char* fieldname, long long& value);
bool xmlbuffer(const char* xmlbuffer, const char* fieldname, unsigned long long& value);
bool xmlbuffer(const char* xmlbuffer, const char* fieldname, double& value);
bool xmlbuffer(const char* xmlbuffer, const char* fieldname, bool& value);
示例一(无重载函数):
示例二(有重载函数):
#define _CRT_SECURE_NO_WARNINGS // 使用 C 风格字符串操作的函数需要定义这个宏
#include <iostream>
using namespace std;
// 解析 xml 字符串。
// xmlbuffer:待解析的 xml 字符串。
// fieldname:字段名。
// value:字段的值。
// ilen:字段值的最大长度,超出 ilen 的内容将会被丢弃,缺省取值 0,表示不限长度。
// 返回值:如果 xmlbuffer 中存在 fieldname 的数据项,返回 true,否则返回 false。
// 注意,调用该函数的时候,必须保证 value 足够大,否则可能会造成内存泄漏。
// <bh>3</bh><name>西施</name><sex>女</sex><age>18</age><yz>漂亮</yz>
bool xmlbuffer(const char* xmlbuf, const char* fieldname, char* value, const size_t ilen = 0)
{
if (xmlbuf==0 || value == 0) return false; // 对形参进行合法性检查。
// 根据字段名,生成带 xml 标签的字段名,例如:用"name"生成<name>和</name>
size_t fieldnamelen = strlen(fieldname);
char* sfieldname = new char[fieldnamelen + 3]; // 动态分配字段名开始标签的内存。
char* efieldname = new char[fieldnamelen + 4]; // 动态分配字段名结尾标签的内存。
memset(sfieldname, 0, fieldnamelen + 3);
memset(efieldname, 0, fieldnamelen + 4);
strcpy(sfieldname, "<"); strcat(sfieldname, fieldname); strcat(sfieldname, ">");
strcpy(efieldname, "</"); strcat(efieldname, fieldname); strcat(efieldname, ">");
// 搜索在 xml 字符串中,出现<name>的位置。
char* start = (char*)strstr(xmlbuf, sfieldname);
if (start == 0) { // 如果 xml 字符串中没有<name>,返回 false。
delete[] sfieldname; delete[] efieldname; return false;
}
// 搜索在 xml 字符串中,出现</name>的位置。
char* end = (char*)strstr(start, efieldname);
if (end == 0) { // 如果 xml 字符串中没有</name>,返回 false。
delete[] sfieldname; delete[] efieldname; return false;
}
size_t valuelen = end - start - fieldnamelen - 2; // 计算字段值的实际长度。
// 从 xml 字符串中截取字段的值。
// <bh>3</bh><name>西施</name><sex>女</sex><age>18</age><yz>漂亮</yz>
// start
if (valuelen <= ilen || ilen == 0)
{
strncpy(value, start + fieldnamelen + 2, valuelen);
value[valuelen] = 0;
}
else
{
strncpy(value, start + fieldnamelen + 2, ilen);
value[ilen] = 0;
}
delete[] sfieldname; delete[] efieldname;
return true;
}
bool xmlbuffer(const char* xmlbuf, const char* fieldname, char& value)
{
char tmpvalue[2];
if (xmlbuffer(xmlbuf, fieldname, tmpvalue, 1) == true)
{
value = tmpvalue[0]; return true;
}
return false;
}
bool xmlbuffer(const char* xmlbuf, const char* fieldname, unsigned char& value)
{
char tmpvalue[2];
if (xmlbuffer(xmlbuf, fieldname, tmpvalue, 1) == true)
{
value = tmpvalue[0]; return true;
}
return false;
}
bool xmlbuffer(const char* xmlbuf, const char* fieldname, int& value)
{
char tmpvalue[21];
if (xmlbuffer(xmlbuf, fieldname, tmpvalue, 20) == true)
{
value = atoi(tmpvalue); return true;
}
return false;
}
bool xmlbuffer(const char* xmlbuf, const char* fieldname, unsigned int& value)
{
char tmpvalue[21];
if (xmlbuffer(xmlbuf, fieldname, tmpvalue, 20) == true)
{
value = atoi(tmpvalue); return true;
}
return false;
}
bool xmlbuffer(const char* xmlbuf, const char* fieldname, long& value)
{
char tmpvalue[21];
if (xmlbuffer(xmlbuf, fieldname, tmpvalue, 20) == true)
{
value = atol(tmpvalue); return true;
}
return false;
}
bool xmlbuffer(const char* xmlbuf, const char* fieldname, unsigned long& value)
{
char tmpvalue[21];
if (xmlbuffer(xmlbuf, fieldname, tmpvalue, 20) == true)
{
value = atol(tmpvalue); return true;
}
return false;
}
bool xmlbuffer(const char* xmlbuf, const char* fieldname, long long& value)
{
char tmpvalue[21];
if (xmlbuffer(xmlbuf, fieldname, tmpvalue, 20) == true)
{
value = atoll(tmpvalue); return true;
}
return false;
}
bool xmlbuffer(const char* xmlbuf, const char* fieldname, unsigned long long& value)
{
char tmpvalue[21];
if (xmlbuffer(xmlbuf, fieldname, tmpvalue, 20) == true)
{
value = atoll(tmpvalue); return true;
}
return false;
}
bool xmlbuffer(const char* xmlbuf, const char* fieldname, double& value)
{
char tmpvalue[21];
if (xmlbuffer(xmlbuf, fieldname, tmpvalue, 20) == true)
{
value = atof(tmpvalue); return true;
}
return false;
}
// 1 0 true false
// <yz>1</yz> 1-漂亮; 0-不漂亮
// <yz>true</yz> true-漂亮;false-不漂亮
bool xmlbuffer(const char* xmlbuf, const char* fieldname, bool& value)
{
char tmpvalue[6];
if (xmlbuffer(xmlbuf, fieldname, tmpvalue, 5) == true)
{
if ((strcmp(tmpvalue, "1") == 0) || (strcmp(tmpvalue, "true") == 0)) value = true;
else value = false;
return true;
}
return false;
}
int main()
{
char sex;
xmlbuffer("<name>西施</name><sex>X</sex>", "sex", sex);
cout << "sex=" << sex << endl; // 显示 sex=X
int age;
xmlbuffer("<name>西施</name><age>18</age>", "age", age);
cout << "age=" << age << endl; // 显示 age=18
long long chip;
xmlbuffer("<name>西施</name><chip>360000000001</chip>", "chip", chip);
cout << "chip=" << chip << endl; // 显示 chip=360000000001
double weight;
xmlbuffer("<name>西施</name><weight>48.75</weight>", "weight", weight);
cout << "weight=" << weight << endl; // 显示 weight=48.75
bool yz;
xmlbuffer("<name>西施</name><yz>1</yz>", "yz", yz);
cout << "yz=" << yz << endl; // 显示 yz=1
xmlbuffer("<name>西施</name><yz>true</yz>", "yz", yz);
cout << "yz=" << yz << endl; // 显示 yz=1
}
 


原文地址:https://blog.csdn.net/qq_60098634/article/details/142314607

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!