Символ новой строки в текстовом документе? - PullRequest
0 голосов
/ 10 ноября 2010

Я написал довольно простую функцию, которая считывает возможные имена игроков и сохраняет их на карте для дальнейшего использования.По сути, в файле каждая строка - это новое имя игрока, но по какой-то причине кажется, что все, кроме фамилии, имеют какой-то невидимый символ новой строки после него.Моя распечатка показывает это так ...

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;
}

Ответы [ 3 ]

2 голосов
/ 10 ноября 2010

Вам действительно нужно рассмотреть возможность использования iostreams и std :: string.Приведенный выше код будет намного проще, если вы использовали доступные вам конструкции C ++.

Проблемы с вашим кодом:

  1. почему вы выделяете буфер для одной строки, котораяразмер файла?
  2. Вы не очищаете этот буфер!
  3. Как ReadLine заполняет буфер line?
  4. предположительно nameLine балловна , начиная с буфера line, если да, то, заданный в std::map, ключ является указателем (char*), а не строкой, как вы ожидали, и указатель являетсятак же!Если они различны (т. Е. Каким-то образом вы читаете строку, а затем перемещаете указатель для каждого имени, то std::map будет содержать запись для каждого игрока, однако вы не сможете найти запись по имени игрока, поскольку сравнение будетСравнение указателей, а не сравнение строк, как вы ожидаете!

Я предлагаю вам взглянуть на реализацию этого с помощью iostreams, вот пример кода (без какого-либо тестирования)

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 набирается с std::string!

1 голос
/ 10 ноября 2010

ReadLine четко включает новую строку в данных, которые он возвращает.Просто проверьте и удалите его:

char *nameLine = filesystem->ReadLine(line, size, file);

// remove any newline...
if (const char* p_nl = strchr(nameLine, '\n'))
    *p_nl = '\0';

(То, что это делает, это перезаписывает символ новой строки новым терминатором NUL, который эффективно обрезает строку ASCIIZ в этой точке.

0 голосов
/ 10 ноября 2010

Скорее всего функция ReadLine также считывает символ новой строки. Я полагаю, в вашем файле нет новой строки в самой последней строке, поэтому вы не получите новую строку для этого имени.

Но пока я не знаю, что такое filesystem, FileHandle_t и Msg, очень трудно определить, где может быть проблема.

...