-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
199 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
#include "FormatString.h" | ||
#include <time.h> | ||
#include <iomanip> | ||
|
||
void _formatTime(std::ostringstream &ss, time_t t) | ||
{ | ||
struct tm tm1; | ||
char szTime[24]; | ||
#ifdef _WIN32 | ||
localtime_s(&tm1, &t); | ||
sprintf_s(szTime, 24, "%04d-%02d-%02d %02d:%02d:%02d", | ||
tm1.tm_year + 1900, tm1.tm_mon + 1, tm1.tm_mday, | ||
tm1.tm_hour, tm1.tm_min, tm1.tm_sec); | ||
#else | ||
localtime_r(&t, &tm1); | ||
snprintf(szTime, 24, "%04d-%02d-%02d %02d:%02d:%02d", | ||
tm1.tm_year + 1900, tm1.tm_mon + 1, tm1.tm_mday, | ||
tm1.tm_hour, tm1.tm_min, tm1.tm_sec); | ||
#endif | ||
|
||
ss << szTime; | ||
} | ||
|
||
void _formatItem(std::ostringstream &ss, const std::string& item, const CArgArray& args) | ||
{ | ||
//{ index[,alignment][ :formatString] } | ||
int index = 0; | ||
int alignment = 0; | ||
std::string fmt; | ||
|
||
char* endptr = NULL; | ||
index = strtol(&item[0], &endptr, 10); | ||
if (index < 0 || index >= args.size()) | ||
{ | ||
return; | ||
} | ||
|
||
if (*endptr == ',') | ||
{ | ||
alignment = strtol(endptr + 1, &endptr, 10); | ||
if (alignment > 0) | ||
{ | ||
ss << std::right << std::setw(alignment); | ||
} | ||
else if (alignment < 0) | ||
{ | ||
ss << std::left << std::setw(-alignment); | ||
} | ||
} | ||
if (*endptr == ':') | ||
{ | ||
fmt = endptr + 1; | ||
} | ||
|
||
args[index]->format(ss, fmt); | ||
return; | ||
} | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
#ifndef _CS_FORMAT_H | ||
#define _CS_FORMAT_H | ||
|
||
#include <string> | ||
#include <vector> | ||
#include <stdlib.h> | ||
#include <iostream> | ||
#include <algorithm> | ||
#include <sstream> | ||
|
||
class CArgArray; | ||
void _formatItem(std::ostringstream &ss, const std::string& item, const CArgArray& args); | ||
void _formatTime(std::ostringstream &ss, time_t t); | ||
|
||
class CArgBase | ||
{ | ||
public: | ||
CArgBase() {} | ||
virtual ~CArgBase() {} | ||
virtual void format(std::ostringstream &ss, const std::string& fmt) = 0; | ||
}; | ||
|
||
template <class T> | ||
class CArg : public CArgBase | ||
{ | ||
public: | ||
CArg(T arg) :_arg(arg) {} | ||
virtual ~CArg(){} | ||
virtual void format(std::ostringstream &ss, const std::string& fmt) | ||
{ | ||
ss << _arg; | ||
} | ||
private: | ||
T _arg; | ||
}; | ||
|
||
//a example of extension | ||
template <> | ||
class CArg<time_t> : public CArgBase | ||
{ | ||
public: | ||
CArg(time_t arg) : _arg(arg) {} | ||
virtual void format(std::ostringstream &ss, const std::string& fmt) | ||
{ | ||
if (fmt[0] == 'T') | ||
{ | ||
_formatTime(ss, _arg); | ||
} | ||
else | ||
{ | ||
ss << _arg; | ||
} | ||
} | ||
private: | ||
time_t _arg; | ||
}; | ||
|
||
class CArgArray : public std::vector<CArgBase*> | ||
{ | ||
public: | ||
CArgArray() {} | ||
~CArgArray() | ||
{ | ||
std::for_each(begin(), end(), [](CArgBase* p){delete p; }); | ||
} | ||
}; | ||
|
||
template <class T> | ||
static void transfer(CArgArray& argArray, T t) | ||
{ | ||
CArgBase* arg = new CArg<T>(t); | ||
argArray.push_back(arg); | ||
} | ||
|
||
template <class T, typename... Args> | ||
static void transfer(CArgArray& argArray, T t, Args... args) | ||
{ | ||
transfer(argArray, t); | ||
transfer(argArray, args...); | ||
} | ||
|
||
template <typename... Args> | ||
std::string CSFormat(const std::string& format, Args... args) | ||
{ | ||
if (sizeof...(args) == 0) | ||
{ | ||
return format; | ||
} | ||
|
||
CArgArray argArray; | ||
transfer(argArray, args...); | ||
size_t start = 0; | ||
size_t pos = 0; | ||
std::ostringstream ss; | ||
while (true) | ||
{ | ||
pos = format.find('{', start); | ||
ss << format.substr(start, pos - start); | ||
if (pos == std::string::npos) | ||
{ | ||
break; | ||
} | ||
if (format[pos + 1] == '{') | ||
{ | ||
ss << '{'; | ||
start = pos + 2; | ||
continue; | ||
} | ||
start = pos + 1; | ||
pos = format.find('}', start); | ||
if (pos == std::string::npos) | ||
{ | ||
ss << format.substr(start-1); | ||
break; | ||
} | ||
|
||
_formatItem(ss, format.substr(start, pos - start), argArray); | ||
|
||
start = pos + 1; | ||
} | ||
|
||
return ss.str(); | ||
} | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
#include "FormatString.h" | ||
#include <string> | ||
#include <iostream> | ||
#include <time.h> | ||
using namespace std; | ||
int main() | ||
{ | ||
string demo = CSFormat("{0,20}|{1,-10}|{2}|{3,30:T}|", 11, "aaa", 3.14, time(NULL)); | ||
cout << demo << endl; | ||
return 0; | ||
} |