高级文件和字符串操作
Advanced File and String Operations
所以我正在DirectX 11程序中开发一个模型加载程序,我遇到了一个我认为独特的问题。所以我花了一些时间寻找解决方案,但没有成功。我的问题是,在我的文件中,有纹理路径和顶点列表,我希望能够挑选出某些部分,并删除一些。下面是我的无纹理三角形示例文件:
T:0$
(0, 5, 0)
(5, 0, 0)
(-5, 0, 0)
^这是旧的,看看下面的编辑^
让我解释一下这里发生了什么。首先,"T:___"是纹理的文件路径。我已将其设置为"0",因为我没有使用纹理。"T:0"之后的"$"是我的程序对文件路径结束和顶点开始的标记。
现在,这是我需要我的程序做的。
1.读取文件,直到达到字符"$"。然后擦除前两个字符("T:")和"$"(如果已添加)。最后将剩余的文本放入一个名为TextureData的字符串中。附言:不要从文件中删除"t:",只删除我的字符串(文件需要保持原样)。
2.将剩余的文本(顶点)放入一个名为VertexData的临时字符串中,然后可能删除括号。。?我很想知道如何做到这一点,但现在可能不使用它。
我希望我把自己和我的问题说得足够清楚。
提前谢谢。
---重要编辑--
我已经改变了我的格式一点,我看了一个.obj文件,并决定这将更容易做到。我的纹理和顶点文件现在看起来像这样:
T:0$
v 0 5 0
v 5 0 0
v -5 0 0
---编辑结束--
这里的代码是我的基础:
模型加载功能:
bool LoadTVF(string FP)
{
ifstream TVFReader;
TVFReader.open(FP);
if (TVFReader.is_open())
{
ReadLine(1); // Function not fully working, need to improve
// Load vertices and texture into strings
TVFReader.close();
return true;
}
else
{
return false;
}
}
ReadLine函数(只是为了组织我的代码并跳到某一行,检索该行的数据并放入字符串中,字符串的剪切和修改需要回到主函数中):
string ReadLine(int character)
{
return lineData; // I know this doesn't work, just don't know what to return?
}
老实说,使用这个ReadLine函数,我不知道自己在做什么。我只是在制作某种框架,向您展示我希望如何组织代码。
再次感谢。
我会这样做:
bool LoadTVF(string FP)
{
ifstream TVFReader;
TVFReader.open(FP);
if (TVFReader.is_open()) {
stringstream buffer;
buffer << TVFReader.rdbuf();
string texture_string = buffer.str();
texture_string = texture_string.substr(2, texture_string.length());
// Removes T:
texture_string.erase(texture_string.begin() + texture_string.find("$"));
// Removes the first occurrence of $
std::cout << texture_string;
/* This will print out:
* 0
* v 0 5 0
* v 5 0 0
* v -5 0 0
*/
TVFReader.close();
return true;
}
else
{
return false;
}
}
这不使用ReadLine
函数,因为它一次加载整个字符串。由于我只是在一开始就处理这个字符串,所以我宁愿将解析和修剪逻辑放在一个地方。
如果必须逐行迭代,那么已经有一种使用getline
:的方法可以做到这一点
bool LoadTVF(string FP)
{
ifstream TVFReader;
TVFReader.open(FP);
if (TVFReader.is_open()) {
string line;
while(getline(TVFReader, line))
{
// Do stuff with each line
}
TVFReader.close();
return true;
}
else
{
return false;
}
}
请注意,这些line
中没有行尾字符。
编辑:根据OP的评论,以下是如何将解析后的文件拆分为单独的字符串:
bool LoadTVF(string FP)
{
ifstream TVFReader;
TVFReader.open(FP);
if (TVFReader.is_open()) {
string header;
getline(TVFReader, header);
header = header.substr(2, header.length());
// Removes T:
header.erase(header.begin() + header.find("$"));
// Removes the first occurrence of $
std::cout << header << std::endl;
// This should print 0, which is the string between T: and $
stringstream buffer;
string line;
while (getline(TVFReader, line))
{
line = line.substr(2, line.length());
// Removes the starting "v "
buffer << line << std::endl;
// We need the end-of-line here because its been stripped
}
string texture_string = buffer.str();
std::cout << texture_string;
/* This will print out:
* 0 5 0
* 5 0 0
* -5 0 0
*/
TVFReader.close();
return true;
}
else
{
return false;
}
}
我想在这里做几点笔记。如果您可以控制文件的结构方式,则不需要$
字符来指示该行的末尾。事实上,有一条换行符应该足以说明这一点。此外,由于后面的每一行都表示矩阵中的一个向量,我认为v
也没有必要。最后,如果文件的名称适当,比如"test.texture"
,那么T:
也可能是不必要的。这样你就知道你正在读取的文件是一个纹理。
这将降低解析这些文件的复杂性,并且作为奖励,还可以减少这些文件的存储大小。
到目前为止,您似乎可以使用getline
逐行读取文件,然后提取必要的信息:通过检查第一个字符来确定"行类型",然后根据类型获取带路径的子字符串或将行拆分为块并将其转换为浮点数。
稍后,当/如果您的文件格式变得更加复杂时,您可能需要编写一个完整的解析器,可能需要使用某种解析器生成器。
- 重载操作程序时出错>>用于类中的字符串 memebr
- 对字符串进行位操作
- 字符串操作 - 字符计数
- 在 c++ 中对字符串进行操作的关系运算符无法按预期工作
- 字符串操作主题消息
- std::字符串串联操作
- 在MySql中使用字符串操作函数有什么问题
- 如何在没有外部库的情况下使用C++03约束执行基于正则表达式的字符串操作
- 使用来自串行端口的字符串数据来操作振镜扫描仪在更高的速度下会出错
- 如何使用 Win32 WCHAR 执行字符串操作
- C 库中是否有任何功能将字符串转换为算术操作
- 如何将字符 a= '+'(或字符串 []) 变成实际操作?
- UTF-8字符串上的位XOR操作可提供非UTF-8输出
- 一个用于操作字符串以在vba中使用的c++dll
- 操作字符串的函数 ( "abcdef" -> "faebdc" )
- 操作字符串c++
- c++:通过函数使用指针操作字符串
- 通过对dll的标准调用操作字符串的问题
- 如何操作字符串小写并存储在同一变量中
- 使用fork() c++在共享内存中操作字符串