- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我写了一个字符串类,想在MFC的CString类中写一个类似Format()
函数的函数。但是当我使用它时,它总是导致一些“随机”错误并且根本不起作用。
我使用 sprintf()
实现此功能,但是当我输入从 va_arg()
获得的参数时,它告诉我该参数无效。通过使用 std::string().c_str()
,这个错误消失了,但我得到了这个错误:
"At 0x00B326A0(Inside UString.exe)Csusing error: 0xC0000005: Access conflict occurs at read location 0x77000073" or it will turn to my
throw()
line.
这里是所有“格式化”函数及其支持的函数代码:
std::string UString::SUBSTR(std::string src, int start, int stop)
{
if (start > stop)
{
return "null";
}
if ((stop - start) > src.length())
{
return "overload";
}
char* tmp = new char[src.length()];
for (int i = start; i <= stop; i++)
{
tmp[i - start] = src[i];
}
std::string ret = std::string(tmp);
delete[] tmp;
return ret;
}
std::wstring UString::STW(const std::string & str)
{
std::wstring ret;
try {
std::wstring_convert< std::codecvt_utf8<wchar_t> > wcv;
ret = wcv.from_bytes(str);
}
catch (const std::exception & e) {
std::cerr << e.what() << std::endl;
}
return ret;
}
bool UString::Matchopt(std::string s)
{
const std::string opt[10] = { "d","o","x","X","c","s","f","ld","lld","lf" };
for (int i = 0; i < 10; i++)
{
if (s == opt[i])
return true;
}
return false;
}
bool UString::IsLegalFormatStringEnd(char c)
{
std::string sg = "doxXsfc";
for (int i = 0; i < sg.length(); i++)
{
if (c == sg[i])
return true;
}
return false;
}
bool UString::IsLegalFormatString(std::string fms)
{
UString ustr = fms;
return ustr.legalstring(std::string("%-0123456789.cdoflsxX"));
}
std::string UString::GetSubFormatString(std::string full,int pos)
{
for (int i = pos; i < full.length(); i++)
{
if (IsLegalFormatStringEnd(full[i]))
{
printf("format string:%s,result:%d\n", SUBSTR(full, pos, i).c_str(), IsLegalFormatString(SUBSTR(full, pos, i)));
if (IsLegalFormatString(SUBSTR(full, pos, i)))
{
return SUBSTR(full, pos, i);
}
else
{
throw("UString: Unlegal Format String");
return "";
}
}
}
throw("UString: Unlegal Format String");
return "";
}
std::string UString::GetCoreString(std::string sfs)
{
UString utmp = sfs;
if (utmp.length() == 0)
{
throw("UString: Cannot get sub string from a empty source string");
}
else if (utmp.length() == 1)
{
if (Matchopt(utmp.std_str()))
{
return utmp.std_str();
}
else
{
throw("UString: Unlegal Format String");
}
}
else if (utmp.length() == 2)
{
if (Matchopt(utmp.substr(1, 1)))
{
return utmp.substr(1, 1);
}
else if (Matchopt(utmp.substr(0, 1)))
{
return utmp.substr(0, 1);
}
else
{
throw("UString: Unlegal Format String");
}
}
else if (Matchopt(utmp.substr(utmp.length() - 1, utmp.length() - 1)))
{
return utmp.substr(utmp.length() - 1, utmp.length() - 1);
}
else if (Matchopt(utmp.substr(utmp.length() - 2, utmp.length() - 1)))
{
return utmp.substr(utmp.length() - 2, utmp.length() - 1);
}
else if (Matchopt(utmp.substr(utmp.length() - 3, utmp.length() - 1)))
{
return utmp.substr(utmp.length() - 3, utmp.length() - 1);
}
else
{
throw("UString: Unlegal Format String");
return "";
}
}
void UString::format(std::string cmd, ...)
{
va_list vl;
int cnt = 0;
for (int i = 0; i < cmd.length(); i++)
{
if (i != (cmd.length() - 1))
{
if ((cmd[i] == '%') && (cmd[i + 1] != '%'))
{
cnt++;
}
}
}
if (cnt == 0)
{
str = std::string(cmd);
return;
}
else
{
va_start(vl, cnt);
std::string* cmdgroup = new std::string[cnt + 1];
int* pos = new int[cnt];
char* tmp = nullptr;
int posi = 0, posold = 0;
for (int i = 0; i < cmd.length(); i++)
{
if (i != (cmd.length() - 1))
{
if ((cmd[i] == '%') && (cmd[i + 1] != '%'))
{
pos[posi] = i;
posi++;
}
}
}
for (int i = 0; i < cnt; i++)
{
std::string full = GetSubFormatString(cmd, pos[i]);
std::string opt = GetCoreString(full);
char* buffer = NULL;
if (opt == "d" || opt == "o" || opt == "x" || opt == "X")
{
int tmpi = va_arg(vl, int);
sprintf(buffer, full.c_str(), tmpi);
}
else if (opt == "c")
{
char tmpc = va_arg(vl, char);
sprintf(buffer, full.c_str(), tmpc);
}
else if (opt == "s")
{
const char* tmpcp = va_arg(vl, char*);
std::string tmps = std::string(tmpcp);
sprintf(buffer, full.c_str(), tmps.c_str());
}
else if (opt == "f")
{
float tmpf = va_arg(vl, float);
sprintf(buffer, full.c_str(), tmpf);
}
else if (opt == "ld")
{
long tmpl = va_arg(vl, long);
sprintf(buffer, full.c_str(), tmpl);
}
else if (opt == "lld")
{
long long tmpll = va_arg(vl, long long);
sprintf(buffer, full.c_str(), tmpll);
}
else if (opt == "lf")
{
double tmpd = va_arg(vl, double);
sprintf(buffer, full.c_str(), tmpd);
}
delete[] buffer;
cmdgroup[i + 1] = std::string(buffer);
}
if (cmd[0] != '%')
{
cmdgroup[0] = SUBSTR(cmd, 0, pos[0] - 1);
}
else
cmdgroup[0] = "";
va_end(vl);
str = "";
for (int i = 0; i < cnt + 1; i++)
{
str = str + cmdgroup[i];
}
delete[] pos;
delete[] tmp;
delete[] cmdgroup;
}
return;
}
bool UString::legalstring(std::string sstr)
{
return legalstring(STW(sstr));
}
bool UString::legalstring(std::wstring wstr)
{
std::wstring ws = STW(str);
for (int i = 0; i < length(); i++)
{
for (int j = 0; j < wstr.length(); j++)
{
if (ws[i] == wstr[j])
break;
else if (j == (wstr.length() - 1))
return false;
}
}
return true;
}
它应该像这样工作:
UString ustr;
ustr.format("test:%d",5);
std::cout<<ustr<<std::endl;
输出应该是:test:5
最佳答案
有一种更快的方法来实现您的Format()
成员函数,使用神秘的vsnprintf()
函数!试试这个:
#include <stdio.h>
#include <stdarg.h>
#include <iostream>
class UString {
public:
char buffer[4096]; // Just to keep the code simple!
UString() : buffer {""} {}
inline void Format(const char* fmt, ...) {
va_list argList; va_start(argList, fmt);
vsnprintf(buffer, 4095, fmt, argList);
va_end(argList);
}
operator char* () { return buffer; }
};
int main()
{
UString test;
printf("Initial: >>>%s<<<\n", test.operator char *());
int i = 12; double d = 3.1415926536; const char* s = "Hello, World!";
test.Format("%s i = %d, d = %lf", s, i, d);
printf("Tested: >>>%s<<<\n", test.operator char *());
// Your test ...
UString ustr;
ustr.Format("test:%d", 5);
std::cout << ustr << std::endl;
return 1;
}
编辑:更正为更“标准”的 vsnprintf()
。
关于c++ - C++17中不定参数函数的错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57722252/
是否有人遇到过 Azure 中的日志流问题,其中出现消息“欢迎,您现在已连接到日志流服务”。是否只是持续每秒发送 10 次垃圾邮件?我现在无法查看我的日志。 2022-07-07T12:48:40
是否有人遇到过 Azure 中的日志流问题,其中出现消息“欢迎,您现在已连接到日志流服务”。是否只是持续每秒发送 10 次垃圾邮件?我现在无法查看我的日志。 2022-07-07T12:48:40
我是一名优秀的程序员,十分优秀!