我写了一个非常简单的函数,它读取可能的播放器名称并将它们存储在地图中供以后使用。基本上在文件中,每一行都是一个新的可能的玩家名称,但由于某种原因,它似乎除了姓之外有一些看不见的新行字符。我的打印出来就是这样......
nameLine = Georgio
Name: Georgio
0
nameLine = TestPlayer
Name: TestPlayer 0
这是实际的代码。我想我需要剥离一些东西,但我不确定我需要检查什么。
bool PlayerManager::ParsePlayerNames()
{
FileHandle_t file;
file = filesystem->Open("names.txt", "r", "MOD");
if(file)
{
int size = filesystem->Size(file);
char *line = new char[size + 1];
while(!filesystem->EndOfFile(file))
{
char *nameLine = filesystem->ReadLine(line, size, file);
if(strcmp(nameLine, "") != 0)
{
Msg("nameLine = %s\n", nameLine);
g_PlayerNames.insert(std::pair<char*, int>(nameLine, 0));
}
for(std::map<char*,int>::iterator it = g_PlayerNames.begin(); it != g_PlayerNames.end(); ++it)
{
Msg("Name: %s %d\n", it->first, it->second);
}
}
return true;
}
Msg("[PlayerManager] Failed to find the Player Names File (names.txt)\n");
filesystem->Close(file);
return false;
}
答案 0 :(得分:2)
你真的需要考虑使用iostreams和std :: string。如果您使用了可用的C ++构造,上面的代码就会简单得多。
代码问题:
ReadLine
如何填充line
缓冲区?nameLine
指向line
缓冲区的开始,如果是这样,在std::map
中给出,键是指针({{1}而不是你期望的字符串,指针是相同的!如果不同(即以某种方式你读取一行然后为每个名称移动指针,那么char*
将包含每个玩家的条目,但是你将无法按玩家名称找到一个条目,因为比较将是一个指针比较,而不是你期望的字符串比较!我建议你看看使用iostream实现这个,这里是一些示例代码(没有任何测试)
std::map
无需进行任何手动内存管理,并使用ifstream fin("names.txt");
std::string line;
while (fin.good())
{
std::getline(fin, line); // automatically drops the new line character!
if (!line.empty())
{
g_PlayerNames.insert(std::pair<std::string, int>(line, 0));
}
}
// now do what you need to
}
键入std::map
!
答案 1 :(得分:1)
ReadLine显然包含它返回的数据中的换行符。只需检查并删除它:
char *nameLine = filesystem->ReadLine(line, size, file);
// remove any newline...
if (const char* p_nl = strchr(nameLine, '\n'))
*p_nl = '\0';
(这样做是用新的NUL终结符覆盖换行符,这有效地截断了那时的ASCIIZ字符串。
答案 2 :(得分:0)
最有可能 ReadLine
函数也会读取换行符。我想你的文件在最后一行没有换行符,因此你没有获得该名称的换行符。
但在我知道filesystem
,FileHandle_t
和Msg
是什么之前,确定问题的位置非常困难。