字符串连接是端到端连接两个字符串的操作。
Kotlin 的多行字符串处理在很多方面都很出色,并且它的 .trimIndent() 功能允许您保持字符串文字与其余代码的缩进,如下所示: 有趣的主要(参数:Arr...
如何得到下面指定的结果? 我尝试使用 LISTAGG 函数,但它并不能消除重复项。 有没有办法消除数据库本身的重复项而不是获取...
我可以使用 require("path").join 来安全地连接 url 吗?
使用 require("path").join 连接 URL 是否安全,例如: require("path").join("http://example.com", "ok"); //返回'http://example.com/ok' require("path").join("http://example...
我有点困惑。我确信由于像 s += "abc" 这样的 str 操作的不变性需要将整个 s 内容复制到内存中的另一个位置,因此可以有效地将字符添加到非常 l...
我想将以下语法存储在Python数据库中,其中k给出的值将根据索引值增加。然而,这个语法不起作用。任何人都可以建议: DATA_LY[“比赛...
程序应该接受两个输入的字符串,将它们连接起来,然后打印。这是我现在拥有的代码,我想知道如何解决这个问题。我还是个新人,所以请耐心等待。谢谢...
C++中std::string连接的原理是什么?它在内存分配中如何工作? 我在探索 Java 中的 leetcode 卡时发现: “串联首先起作用
我有一个作业要编写一个函数,该函数采用两个 C 字符串参数并将第二个参数附加到第一个参数,就像 strcat 函数一样,但不使用所述函数。然后,写一个主要的驱动...
Java 中的字符串连接是否总是会导致在内存中创建新字符串?
我有一条很长的字符串,不适合屏幕的宽度。例如。 String longString = "这个字符串很长,不适合屏幕的宽度,所以必须水平滚动...
为什么 `paste` 会改变 Sys.time 和 time.duration 的字符串输出?
我很难理解为什么 R 中的 {base} 粘贴函数似乎改变了它打印某些变量的方式。 开始时间 <- Sys.time() result <- sum(1:10000) dur_time <- Sys....
如何在 Zig 中连接编译时已知长度的以下字符串? const url = "https://github.com/{}/reponame"; const 用户 = "Himujjal"; const Final_url = 你...
我刚刚复习我的 C++。我尝试这样做: #包括 使用 std::cout; 使用 std::endl; 无效 printStuff(int x); int main() { 打印东西(10); 返回0; } 无效打印...
Oracle DB - 创建表为 - 导致“ORA-01489:字符串连接的结果太长”
我在一个存储过程中发现了一个奇怪的行为,该存储过程在将标准化报告历史记录到我们的 Oracle 数据库中时在 99% 的情况下都能正常工作。 对于某些报告,我收到错误 ORA-01489:...的结果
我的以下代码有错误: $name = "布什 DVD 播放器"; 打印“上一个”; 页面上显示以下内容...
C++ 串联操作数 '+' 不同形式 ' '。 在学校*,在 C++ 中,我们总是使用“+”运算符来连接字符串..例如: 字符串a =“你好”+“世界。”; 但为了...
回溯(最近一次调用最后一次): 文件“c:\Users\user\Desktop\September Report empCodeRunnerFile.python”,第 140 行,位于 x1= -b/(2ac) + (math.sqrt(disc))/(2ac), str(j) ^ 名称错误:名称...
如何在python3中为cursor.execute制作灵活的参数列表?
其实我想根据变量值的状态来增减mysql的查询项和值(参数)。 根据我的场景,我需要进行灵活的 mysql 查询
我需要连接两个 const 字符,如下所示: const char *one = "你好"; const char *two = "世界"; 我该怎么做呢? 我从第三方库传递了这些 char*s...
Var + formatdate 的 Terraform 引号语法
Terraform = v1.8.2 AWS 提供商 = >= 5.30 来自 hashicorp/aws 尝试使用 terraform 创建 AWS 资源名称以包含其创建日期+时间。 这是为了序列化资源
我正在尝试在编译时连接类似字符串的对象。在这篇文章的帮助下,我想出了这样的东西: #包括 #包括 #包括 我试图在编译时连接类似字符串的对象。在这篇文章的帮助下,我想出了这样的东西: #include <cstddef> #include <algorithm> #include <array> #include <cstring> #include <string> #include <string_view> template <std::size_t N> class ConstexprChars { private: std::array<char, N> _string; template <std::size_t S> friend class ConstexprChars; template <std::size_t S1, std::size_t S2> constexpr ConstexprChars(const std::array<char, S1> s1, const std::array<char, S2> s2) : _string() { std::copy(s1.begin(), s1.end() - 1, _string.begin()); std::copy(s2.begin(), s2.end() - 1, _string.begin() + S1 - 1); } public: constexpr ConstexprChars(const char (&str)[N]) : _string() { std::copy(&str[0], &str[0] + N, _string.begin()); } constexpr ConstexprChars(const std::array<char, N> str) : _string() { std::copy(&str[0], &str[0] + N, _string.begin()); } constexpr ConstexprChars(std::string_view str) : _string() { std::copy(str.data(), str.data() + N, _string.begin()); } template <std::size_t S> constexpr auto operator+(const ConstexprChars<S> other) const { return ConstexprChars<N + other._string.size() - 1>(_string, other._string); } [[nodiscard]] constexpr auto c_str() const { return _string.data(); } }; template <std::size_t N, std::size_t... Ns> constexpr auto cconcat_impl(const char (&first)[N], const char (&... rest)[Ns]) { if constexpr (!sizeof...(Ns)) { return ConstexprChars<N>{first}; } else { return ConstexprChars<N>{first} + cconcat_impl(rest...); } } template <std::size_t... Ns> constexpr auto cconcat(const char (&... strings)[Ns]) { return cconcat_impl(strings...); } #include <iostream> int main() { // this works; constexpr const char name[] = "Edward"; constexpr auto joined1 = cconcat("name=", name); std::cout << joined1.c_str() << std::endl; // this does not work: // constexpr std::string_view value = "42"; // essentially same as constexpr const char* // constexpr auto joined2 = cconcat("value=", value); // std::cout << joined2.c_str() << std::endl; return 0; } 但是,这仅适用于字符串文字和字符数组。有没有办法扩展其他编译时类似字符串对象的功能? 编辑: 正如@Oersted所建议的,实现这一目标的一种方法是添加这些重载和宏方案(为了简单起见,忽略了混合搭配的可能性): constexpr std::size_t cptr_size(const char* cptr) { return std::string_view{cptr}.length() + 1; } template <std::size_t N> constexpr auto make_array(const char* cptr) { std::array<char, N> arr; std::copy_n(cptr, N, arr.data()); return arr; } #define MAKEARRAY(str) make_array<cptr_size(str)>(str) template <std::size_t N, std::size_t... Ns> constexpr auto cconcat_impl(const std::array<char, N> first, const std::array<char, Ns>... rest) { if constexpr (!sizeof...(Ns)) { return ConstexprChars<N>{first}; } else { return ConstexprChars<N>{first} + cconcat_impl(rest...); } } template <std::size_t... Ns> constexpr auto cconcat(const std::array<char, Ns>... strings) { return cconcat_impl(strings...); } 那么,我们可以这样做: int main() { constexpr const char* value = "42"; constexpr auto joined2 = cconcat(MAKEARRAY("value="), MAKEARRAY(value)); std::cout << joined2.c_str() << std::endl; return 0; } 但是,这改变了 API。是否可以在保留相同 API 的同时实现这一目标?也就是说,是否可以有这个: int main() { constexpr const char* value = "42"; constexpr auto joined2 = cconcat("value=", value); std::cout << joined2.c_str() << std::endl; return 0; } 您需要将串联结果存储在编译时大小的数组中(例如std::array)。但是 std::string_view::size 是其值的一部分(而不是其类型),并且不能用于确定串联函数的结果类型。最直接的方法是定义一个 fixed_string 类模板并将大小放入其类型元数据中。类模板可以将转换运算符声明为 std::array、std::string_view 和 std::string。对于运行时串联,您需要在串联序列中提供至少一个 std::string 类的实例。如果使用 operator+ 来执行串联,语法将保持一致: template<std::array val> struct fixed_string{ using this_arr_t = std::remove_cv_t<decltype(val)>; using value_type = this_arr_t::value_type; using string_view = std::basic_string_view<value_type>; consteval static auto size() {return size(val)-!back(val);}; consteval operator std::basic_string_view<value_type>() const{return string_view{data(val), this->size()};}; constexpr operator std::basic_string<value_type>() const{return std::basic_string{ string_view{*this}};}; consteval static auto begin() {return std::begin(string_view{fixed_string{}});}; consteval static auto end() {return std::end(string_view{fixed_string{}});}; template<std::size_t N> consteval static auto arrcat(array<value_type, N> rhs) ->std::array<value_type, size() + N> { std::array<value_type, size() + N> res; std::ranges::copy(rhs, std::ranges::copy(fixed_string{}, begin(res)).second); return res; }; template<std::array rhs> consteval fixed_string<arrcat(rhs)> operator+(fixed_string<rhs>) {return {};}; private: // I would like the class empty }; template<std::array val> consteval fixed_string<val> operator""_fxstr() {return {};}; auto str = "this"_fxstr + " is a "_fxstr + "std::string"s; 为了清楚起见,我留下了很多实现细节。例如:我会从末尾删除空终止符,但人们可能想保留它。 但是 ` 提供了一种更简单的方法来零努力地实现这一目标: auto str = std::array{ "this"sv , "is"sv , "a"sv , "std::string"s } | std::views::join("_") | std::ranges::to<std::string>(); 如果输入是,则join的结果可以是constexpr。但在被收集为 string 或 vector 与 ranges::to 之前,它不会是连续的范围。 最后一点 - 正如评论中已经提到的 - 是避免定义与 Qt 等著名库中的名称相同的标识符: QObject 是与您的预期用途无关的名称,并且是抽象基类名称Qt。 总结我的评论,我实现了这个片段。是否满足您的需求: #include <algorithm> #include <array> #include <cstddef> #include <iostream> #include <string_view> namespace Details { template <size_t N> struct StringWrapper { std::array<char, N> value; std::size_t size; constexpr explicit(false) StringWrapper(const char (&str)[N]) : size(N) { std::copy_n(static_cast<const char *>(str), N, value.data()); } }; } // namespace Details template <Details::StringWrapper head, Details::StringWrapper tail> class SConcat { constexpr static std::array<char, head.size + tail.size - 1> init() { std::array<char, head.size + tail.size - 1> conc; std::copy(std::cbegin(head.value), std::cend(head.value) - 1, std::begin(conc)); std::copy(std::cbegin(tail.value), std::cend(tail.value), std::begin(conc) + head.size - 1); return conc; } static constexpr std::array<char, head.size + tail.size - 1> data = init(); public: static constexpr std::string_view as_sv() { return {data.data()}; } }; int main() { constexpr char value[] = "42"; const std::string_view conc{SConcat<"value=", value>::as_sv()}; std::cout << conc << '\n'; return static_cast<int>(conc[1] == 'a'); } 直播 我认为它可以得到显着的完善,但它给出了主要思想。 First StringWrapper 只是一种将原始字符串隐式转换为可用作 SConcat 的 CNTTP 对象的方法(因此需要 C++20)。 因此,SConcat为其声明中使用的每对字符串提供了唯一的类型,并且串联结果保存在提供存储的静态成员变量data中。 通过string_view方法最终可以得到as_sv()。 (NB1,通过删除 std::cout 部分,您可以看到编译器如何优化所有内容,然后是程序集: main: mov eax, 1 ret NB2 static_cast 只是为了消除一些误报警告。 ) 编辑:支持各种字符串文字声明的替代方案,按照 op 的要求,有点详细。 #include <algorithm> #include <array> #include <cstddef> #include <string> #include <string_view> // #define PROVEOPTIM #ifndef PROVEOPTIM #include <iostream> #endif namespace Details { constexpr std::size_t MySize(const char *str) { std::string tmp{str}; return tmp.length(); } template <std::size_t N> constexpr auto MakeArray(const char *str) { std::array<char, N + 1> arr; std::copy_n(str, N + 1, arr.data()); return arr; } } // namespace Details #define MAKEARRAY(str) Details::MakeArray<Details::MySize(str)>(str) template <std::array head, std::array tail> class SConcat { constexpr static std::array<char, head.size() + tail.size() - 1> init() { std::array<char, head.size() + tail.size() - 1> conc; std::copy(std::cbegin(head), std::cend(head) - 1, std::begin(conc)); std::copy(std::cbegin(tail), std::cend(tail), std::begin(conc) + head.size() - 1); return conc; } static constexpr std::array<char, head.size() + tail.size() - 1> data = init(); public: static constexpr std::string_view as_sv() { return {data.data()}; } }; int main() { constexpr const char *value = "42"; constexpr const char value2[] = "3.14"; const std::string_view conc{ SConcat<MAKEARRAY("value="), MAKEARRAY(value)>::as_sv()}; const std::string_view conc2{ SConcat<MAKEARRAY("value="), MAKEARRAY(value2)>::as_sv()}; #ifndef PROVEOPTIM std::cout << conc << '\n'; std::cout << conc2 << '\n'; #endif return static_cast<int>(conc[1] == 'a'); } 直播 它依赖于从指向作为 std::array 或 const char* 传递的空终止字符串的指针显式构建 const char[]。宏 MAKEARRAY 将两个操作合并为一个:获取大小作为编译时常量,并从用于获取大小的同一源复制数据。 显然,如果“字符串”不是以 null 结尾,则结果是未定义的。