С чего начать !!!!
Плохая практика. Один на линию!
std::string filename, token, line;
Они не используются. Удалить их.
int positionLine(0);
int positionToken(0);
Не извлекайте указатель на строку в новую переменную.
Если имя файла изменено, файл становится недействительным.
Это безопасно использовать только тогда, когда результат передается в функцию.
const char *file=filename.c_str();
std::ifstream input(file, std::ios::in);
Таким образом, вы должны сделать это так.
std::ifstream input(file.c_str());
Здесь. Вы объявляете совершенно новую переменную input
. Эта переменная не имеет ничего общего с другой переменной input
. Эта версия уничтожается, когда выходит из области видимости в конце цикла while.
while (!input.is_open())
{
// <STUFF DELETED>
std::ifstream input(file, std::ios::in);
}
Это очень распространенная ошибка.
Тестирование на хорошее состояние здесь (обычно) неправильно. Это потому, что обычно вы хотите, чтобы цикл завершился, когда вы дойдете до конца файла. Но последнее чтение фактически читает до конца файла, но не до конца файла, и, таким образом, оно не вызывает флаг EOF, и цикл повторяется. Тогда следующее чтение не удастся:
while (input.good() && numOfLine < MAX_RECORDS)
{
getline (input,line);
Лучшая версия:
while (getline (input,line) && numOfLine < MAX_RECORDS)
{
Здесь вы правильно поняли:
while (getline(inputss, token, ',') && row < ROWS )
{
Здесь вы увеличиваете строку для индексации до tempArray
. Но я не вижу, где эта строка сбрасывается до 0.
tempArray[row] = token;
row++;
Edit:
На основе приведенных ниже боевых коментариев Бо.
Технически в этом нет ничего плохого:
const char *file=filename.c_str();
std::ifstream input(file, std::ios::in);
Здесь file
используется немедленно и никогда не используется снова. Из опыта я обнаружил, что, делая это, вы вводите новую переменную в контекст, которую другие могут свободно использовать повторно. Обычно это не проблема, но этот конкретный указатель может незаметно стать недействительным (если объект имени файла изменяется, то указатель файла может потенциально стать недействительным).
Это проблема обслуживания и особенно опасна, когда несколько разработчиков изменяют код. Если переменная file
позже используется в коде разработчиком 'A', а разработчик 'B', то приходит и добавляет код, который изменяет переменную filename
, теперь вы находитесь в ситуации, которая может быть опасной.
Таким образом, всегда безопаснее НЕ хранить указатели, которые могут стать невидимыми недействительными. Таким образом, единственный безопасный способ их использования - это параметры функций.
std::ifstream input(filename.c_str(), std::ios::in);
Еще одна ситуация, с которой я недавно столкнулся, была та же проблема в несколько ином контексте:
QString path(<Some String>);
char* file = path.toLatin1().data();
readFile(file);
Проблема в том, что toLatin () возвращает объект QByteArray. Этот объект возвращается по значению и не присваивается какой-либо переменной и поэтому является временным. Временные объекты уничтожаются в конце выражения, поэтому метод data (), который возвратил указатель на внутреннюю часть QByteArray, присвоил переменной file
значение, которое недопустимо, как только ';' ударил.
Безопасный способ сделать это - передать результат непосредственно в качестве параметра функции:
readFile(path.toLatin1().data());