【发布时间】:2021-02-15 16:12:19
【问题描述】:
下面的代码存在运行时问题。
目的是“识别”输入字符串中的格式(%s %d 等)。
为此,它返回一个与数据类型匹配的整数。
然后提取的类型在其他函数中进行操作/处理。
我想澄清一下,我的目的不是在字符串中编写格式化类型(snprintf 等),而只是识别/提取它们。
问题是我的应用程序崩溃并出现错误:
Debug Assertion Failed!
Program:
...ers\Alex\source\repos\TestProgram\Debug\test.exe
File: minkernel\crts\ucrt\appcrt\convert\isctype.cpp
Line: 36
Expression: c >= -1 && c <= 255
我的代码:
#include <iostream>
#include <cstring>
enum Formats
{
TYPE_INT,
TYPE_FLOAT,
TYPE_STRING,
TYPE_NUM
};
typedef struct Format
{
Formats Type;
char Name[5 + 1];
} SFormat;
SFormat FormatsInfo[TYPE_NUM] =
{
{TYPE_INT, "d"},
{TYPE_FLOAT, "f"},
{TYPE_STRING, "s"},
};
int GetFormatType(const char* formatName)
{
for (const auto& format : FormatsInfo)
{
if (strcmp(format.Name, formatName) == 0)
return format.Type;
}
return -1;
}
bool isValidFormat(const char* formatName)
{
for (const auto& format : FormatsInfo)
{
if (strcmp(format.Name, formatName) == 0)
return true;
}
return false;
}
bool isFindFormat(const char* strBufFormat, size_t stringSize, int& typeFormat)
{
bool foundFormat = false;
std::string stringFormat = "";
for (size_t pos = 0; pos < stringSize; pos++)
{
if (!isalpha(strBufFormat[pos]))
continue;
if (!isdigit(strBufFormat[pos]))
{
stringFormat += strBufFormat[pos];
if (isValidFormat(stringFormat.c_str()))
{
typeFormat = GetFormatType(stringFormat.c_str());
foundFormat = true;
}
}
}
return foundFormat;
}
int main()
{
std::string testString = "some test string with %d arguments"; // crash application
// std::string testString = "%d some test string with arguments"; // not crash application
size_t stringSize = testString.size();
char buf[1024 + 1];
memcpy(buf, testString.c_str(), stringSize);
buf[stringSize] = '\0';
for (size_t pos = 0; pos < stringSize; pos++)
{
if (buf[pos] == '%')
{
if (buf[pos + 1] == '%')
{
pos++;
continue;
}
else
{
char bufFormat[1024 + 1];
memcpy(bufFormat, buf + pos, stringSize);
bufFormat[stringSize] = '\0';
int typeFormat;
if (isFindFormat(bufFormat, stringSize, typeFormat))
{
std::cout << "type = " << typeFormat << "\n";
// ...
}
}
}
}
}
正如我在代码中评论的那样,使用第一个字符串一切正常。使用第二个时,应用程序崩溃。
我还想问你有没有更好/更高效的方法来识别字符串中的类型“%d %s etc”? (甚至不一定返回一个 int 来识别它)。
谢谢。
【问题讨论】:
-
memcpy(bufFormat, buf + pos, stringSize);复制的字符串多于剩余的字符串(stringSize - pos似乎更合适)... 不知道为什么你也复制到中间缓冲区,因为你可能直接使用std::string和偏移量(@ 987654326@).
标签: c++ visual-studio string-formatting stdstring