dustpg大神给我的代码,总有一天我要完全读懂!
2015-09-29 00:23
435 查看
帖子:http://bbs.csdn.net/topics/391835837
PS:赋值字符串技巧:如果是中间的一段字符串(末尾没有 '\0' 所以不能直接调用 strcpy),
可以先 memcpy,然后将 buff 的最后一个 char 赋值为 '\0',就不用调用 memset 或 bzero 对整块 buff 清零了
要效率就肯定要加限制, 这是我的限制:
1. 使用时要保证原字符串对象的有消息 -> 可以直接使用原来的数据避免复制
2. 使用‘字符指针’+‘长度模式, 虽然C风格的字符串是用null字符结尾, 但是世界上又不是
全是只给个字符指针, 比如fwrite要给长度, 可以代替fprintf,
Windows有些API也是需要给长度的, 这样避免字符串的复制
3.实在需要null结尾指针,
3.1 可以使用std::string::assign,
3.2 也可以提供支持, 但是要尽可能的少用,因为用一次就复制一次
代码如下, SubString ::get的第二个参数是一个lambda,
A. 如果这个lambda有两个参数, 则认为是(const char* str, size_t len), 参考上面的行为2
B. 如果这个lambda有一个参数, 则认为是(const char* str), 参考上面的行为3
PS:赋值字符串技巧:如果是中间的一段字符串(末尾没有 '\0' 所以不能直接调用 strcpy),
可以先 memcpy,然后将 buff 的最后一个 char 赋值为 '\0',就不用调用 memset 或 bzero 对整块 buff 清零了
要效率就肯定要加限制, 这是我的限制:
1. 使用时要保证原字符串对象的有消息 -> 可以直接使用原来的数据避免复制
2. 使用‘字符指针’+‘长度模式, 虽然C风格的字符串是用null字符结尾, 但是世界上又不是
全是只给个字符指针, 比如fwrite要给长度, 可以代替fprintf,
Windows有些API也是需要给长度的, 这样避免字符串的复制
3.实在需要null结尾指针,
3.1 可以使用std::string::assign,
3.2 也可以提供支持, 但是要尽可能的少用,因为用一次就复制一次
代码如下, SubString ::get的第二个参数是一个lambda,
A. 如果这个lambda有两个参数, 则认为是(const char* str, size_t len), 参考上面的行为2
B. 如果这个lambda有一个参数, 则认为是(const char* str), 参考上面的行为3
#include <vector> #include <string> #include <cstdint> // type helper with c++ tuple template <typename T> struct type_helper : public type_helper<decltype(&T::operator())> {}; // type helper template <typename ClassType, typename ReturnType, typename... Args> struct type_helper<ReturnType(ClassType::*)(Args...) const> { // number of arguments enum : size_t { arity = sizeof...(Args) }; }; class SubString { static constexpr size_t BUFFER_LENGTH = 4096; using SUBDATA = uint32_t; using String = std::string; struct SUBSTRDATA { SUBDATA offset; SUBDATA length; }; using Vector = std::vector<SUBSTRDATA>; private: struct string_helper { string_helper(const char* str, size_t len) noexcept { if (len >= BUFFER_LENGTH) { data = reinterpret_cast<char*>(::malloc(len + 1)); } if (data) { ::memcpy(data, str, sizeof(char) * len); data[len] = 0; } } ~string_helper() noexcept { if (data && data != buffer) ::free(data); } char* data = buffer; char buffer[BUFFER_LENGTH]; }; template<size_t ArgNum> struct get_helper{}; template<> struct get_helper<1> { template<typename T> static auto get(const char* str, size_t len, T lam) { string_helper data(str, len); return lam(data.data); } }; template<> struct get_helper<2> { template<typename T> static auto get(const char* str, size_t len, T lam) { return lam(str, len); } }; public: // split auto split(const String& src, const char* token) { vc.clear(); data = &src; String::size_type end = 0, begin = 0; auto token_length = std::strlen(token); SUBSTRDATA sbdata; while (end != String::npos) { end = src.find(token, begin); sbdata.offset = SUBDATA(begin); if (String::npos == end) { sbdata.length = SUBDATA(src.length() - begin); } else { sbdata.length = SUBDATA(end - begin); } vc.push_back(sbdata); begin = end + token_length; } } // size auto size() { return vc.size(); } // get template<typename T> auto get(size_t index, T func) { auto& ele = vc[index]; const char* str = data->data() + ele.offset; return get_helper<type_helper<T>::arity>::get(str, size_t(ele.length), func); } private: // const String* data = nullptr; // Vector vc; }; auto main() ->int { std::string str = "ABCDEFABCDEFABCDEF"; { SubString sst; sst.split(str, "CD"); for (size_t i = 0; i < sst.size(); ++i) { sst.get(i, [](const char* str, size_t len) noexcept { for (size_t j = 0; j < len; ++j) std::putchar(str[j]); std::putchar('\r'); std::putchar('\n'); }); } std::printf("============\r\n"); for (size_t i = 0; i < sst.size(); ++i) { sst.get(i, [](const char* str) noexcept { std::printf("%s\r\n", str); }); } } return 0; }--EOF--
相关文章推荐
- (转)CGI、FastCGI、PHP-FPM
- JDK 源码解析 —— AtomicInteger
- 基于java config的springSecurity--单元测试
- #322 (div.2) D. Three Logos
- effective c++绝不在构造和析构过程中调用virtual函数
- 新人学ruby---ruby中的模块
- C++类中的main函数
- 四个PHP非常实用的功能
- PHP比较运算符的详细介绍
- PHP类的封装与继承详解
- PHP代码优化技巧小结
- php猜单词游戏
- php正则匹配文章中的远程图片地址并下载图片至本地
- 解决php表单重复提交实现方法
- 网页从弹窗页面单选框传值至父页面代码分享
- 这样写更容易让别人能读懂你的代码
- 类初始化顺序
- 分布式调度QUARTZ+SPRING
- Spring数据交换方式
- 条款48:认识template元编程