我必须用sprintf格式化std::string,并将其发送到文件流。我该怎么做呢?
当前回答
你可以试试这个:
string str;
str.resize( _MAX_PATH );
sprintf( &str[0], "%s %s", "hello", "world" );
// optionals
// sprintf_s( &str[0], str.length(), "%s %s", "hello", "world" ); // Microsoft
// #include <stdio.h>
// snprintf( &str[0], str.length(), "%s %s", "hello", "world" ); // c++11
str.resize( strlen( str.data() ) + 1 );
其他回答
可以使用iomanip头文件格式化cout中的c++输出。 在使用类似的任何helper函数之前,请确保包含iomanip头文件 Setprecision, setfill等等。
下面是我过去用来在向量中打印平均等待时间的代码片段,这是我“累积”的。
#include<iomanip>
#include<iostream>
#include<vector>
#include<numeric>
...
cout<< "Average waiting times for tasks is " << setprecision(4) << accumulate(all(waitingTimes), 0)/double(waitingTimes.size()) ;
cout << " and " << Q.size() << " tasks remaining" << endl;
下面是如何格式化c++流的简要描述。 http://www.cprogramming.com/tutorial/iomanip.html
这是谷歌的做法: facebook也以类似的方式:StringPrintf (Apache许可证) 两者都提供了一个方便的StringAppendF。
template<typename... Args>
std::string string_format(const char* fmt, Args... args)
{
size_t size = snprintf(nullptr, 0, fmt, args...);
std::string buf;
buf.reserve(size + 1);
buf.resize(size);
snprintf(&buf[0], size + 1, fmt, args...);
return buf;
}
使用C99 snprintf和c++ 11
下面是@iFreilicht答案的稍微修改版本,更新到c++ 14(使用make_unique函数而不是原始声明),并增加了对std::string参数的支持(基于Kenny Kerr的文章)
#include <iostream>
#include <memory>
#include <string>
#include <cstdio>
template <typename T>
T process_arg(T value) noexcept
{
return value;
}
template <typename T>
T const * process_arg(std::basic_string<T> const & value) noexcept
{
return value.c_str();
}
template<typename ... Args>
std::string string_format(const std::string& format, Args const & ... args)
{
const auto fmt = format.c_str();
const size_t size = std::snprintf(nullptr, 0, fmt, process_arg(args) ...) + 1;
auto buf = std::make_unique<char[]>(size);
std::snprintf(buf.get(), size, fmt, process_arg(args) ...);
auto res = std::string(buf.get(), buf.get() + size - 1);
return res;
}
int main()
{
int i = 3;
float f = 5.f;
char* s0 = "hello";
std::string s1 = "world";
std::cout << string_format("i=%d, f=%f, s=%s %s", i, f, s0, s1) << "\n";
}
输出:
i = 3, f = 5.000000, s = hello world
如果需要,可以随意将这个答案与原始答案合并。
我现在将为Visual Studio编写版本,希望有一天有人会让它变得可移植。(怀疑需要用vsnwprintf替换_vsnwprintf之类的东西。)
您需要使用项目配置中的define _CRT_SECURE_NO_WARNINGS来禁用已弃用的警告。
我使用_vsnwprintf与第一个参数作为nullptr能够估计缓冲区大小,保留wstring缓冲区,然后格式化字符串直接到缓冲区。
不确定为什么需要禁用已弃用警告,因为相同方法调用(_vsnwprintf_s)的安全版本不能使用nullptr作为输入。怀疑需要报告给微软c++团队。
这个版本应该同时使用- string类或wstring类。
如果你发现任何错误或不一致,请再问一次,我会尽力修复它。
stringHelpers.h:
#pragma once
#include <string>
//
// Formats string/wstring according to format, if formatting fails (e.g. invalid %s pointer - returns empty string)
//
template <typename T>
std::basic_string<T> sFormat(const T* format, ...)
{
va_list args;
va_start(args, format);
int size;
if constexpr (std::is_same_v<T, char>)
size = vsnprintf(nullptr, 0, format, args);
else
size = _vsnwprintf(nullptr, 0, format, args);
size++; // Zero termination
std::basic_string<T> s;
s.resize(size);
if constexpr (std::is_same_v<T, char>)
vsnprintf(&s[0], size, format, args);
else
_vsnwprintf(&s[0], size, format, args);
va_end(args);
return s;
}
以上是代码示例,可以复制。我将维护工作版本在我自己的仓库在github:
https://github.com/tapika/cppscriptcore/blob/master/SolutionProjectModel/helpers.h#L12
推荐文章
- 如何在Python中按字母顺序排序字符串中的字母
- 为什么标准迭代器范围是[begin, end]而不是[begin, end]?
- c++双地址操作符?(& &)
- python: SyntaxError: EOL扫描字符串文字
- PHP子字符串提取。获取第一个'/'之前的字符串或整个字符串
- 格式化XML字符串以打印友好的XML字符串
- 函数标题中的箭头操作符(->)
- 如何在c++中初始化一个向量
- 返回类型为'?:'(三元条件运算符)
- 当分配vector时,它们使用的是堆上的内存还是堆栈上的内存?
- 双引号vs单引号
- 互斥实例/教程?
- 如何知道一个字符串开始/结束在jQuery特定的字符串?
- 如何添加一个'或'条件在#ifdef
- 纯虚函数的实现