字符串连接是端到端连接两个字符串的操作。
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 结尾,则结果是未定义的。
如何避免在加入编译时 string_views 时指定编译时大小?
我正在尝试在编译时连接 string_views。在这篇文章的帮助下,我想出了这样的东西: #包括 #包括 #包括 #在...
我的地址分为 5 列: 地址第一行 地址行2 地址行3 地址行4 国家 我想将它们连接成一列,并用逗号分隔每个地址行。如果地址...
如何将 promoPrice 变量打印为字符串的一部分,仅需 4.67 美元? ${(促销价格!= null)? “只需 $${promoPrice}”:“免费”} 如何获取 promoPrice 变量作为字符串 ONLY $4.67 的一部分进行打印? <c:set var="promoPrice" value="4.67" /> <p>${(promoPrice != null) ? "ONLY $${promoPrice}" : "FREE"}</p> 如果您已经使用 EL 3.0(Java EE 7;WildFly、Tomcat 8+、GlassFish 4+、Payara、WAS 9+ 等),那么您可以使用新的 += 运算符: <p>${not empty promoPrice ? 'ONLY $' += promoPrice : 'FREE'}</p> 如果您尚未使用 EL 3.0,则可以使用 EL 2.2(Java EE 6;JBoss AS 6/7、Tomcat 7、GlassFish 3、WAS 8 等)通过参数调用直接方法的功能,然后应用该功能于String#concat(): <p>${not empty promoPrice ? 'ONLY $'.concat(promoPrice) : 'FREE'}</p> 或者,如果您甚至还没有使用 EL 2.2(Java EE 5 或更早版本;JBoss AS 5- Tomcat 6-、WAS 7- 等),则使用 JSTL <c:set> 使用连接的值创建一个新的 EL 变量只是内联值: <c:set var="promoPriceString" value="ONLY $${promoPrice}" /> <p>${not empty promoPrice ? promoPriceString : 'FREE'}</p> 在您的特定情况,另一种方法是将表达式分成两部分: <p>${not empty promoPrice ? 'ONLY $' : 'FREE'}${promoPrice}</p> 如果 ${promoPrice} 为 null 或空,则无论如何都不会打印。 直接jstl方式 <c:set var="promoPrice" value="4.67" /> <p> <c:choose> <c:when test="${(promoPrice != null)}"> ONLY $${promoPrice} </c:when> <c:otherwise> FREE <c:otherwise> </c:choose> </p> 与 EL 2.0+ 兼容的字符串连接的一个简单而强大的解决方案是使用中间变量: <c:set var="promoPrice" value="4.67" /> <c:set var="priceText" value="ONLY ${promoPrice}" /> <p>${(promoPrice != null) ? priceText : "FREE"}</p> 根据 @BalusC,从 EL 2.2 开始,您可以使用 String#concat() 方法进行串联,从 EL 3.0 开始,您可以使用新的 += 运算符来实现此目的。 我做了类似的事情,我有一个变量mathjaxUrl,我想联系它其他字符串 <c:set var="mathjaxUrl" value="https://cdnjs.cloudflare.com/ajax/libs/mathjax" /> ... some other stuff here <c:set var="mathjaxUrl" value="${mathjaxUrl}?config=TeX-AMS-MML_HTMLorMML" /> 希望这对你有帮助 这行不通? <c:set var="promoPrice" value="4.67" /> <p>${(promoPrice != null) ? "ONLY $"${promoPrice} : "FREE"}</p> 请注意,${promoPrice} 位于引号之外。这看起来是最简单的解决方案。
我正在尝试解决这个 HackerRank 挑战: 已经声明了 3 个变量:i(整数)、d(双精度)和 s(字符串)。 我必须声明另外 3 个与前一个类型相同的变量,要求
我正在 TI-TM4C129X ARM 板上工作,并尝试编写一个 LOG 机制。当我从任务中调用它时,它工作得很好,尽管我在用计时器调用它时遇到了问题。据我了解,.. .
我尝试使用 concat() 函数的返回作为 text() 函数的参数,但它只是返回 concat()
我在 Excel 中使用嵌套函数时遇到问题。我想以某种方式显示日期(例如“2024 年 4 月 15 日星期一”),因此我使用了 text() 。我也希望能够...