Преобразование / разбор строк и удвоений указателя - PullRequest
0 голосов
/ 19 сентября 2011

Назначение:

  1. Считывание информации из текстового файла (выполнено)

  2. Извлечение только частей текстового файла с использованием метода substr (выполнено)

  3. Сохранение информации в переменных экземпляра (нужна помощь)

Вот код, с которым у меня возникли проблемы:

string* lati;
lati = new string(data.substr(0, data.find_first_of(",")));

double* latDub;
latDub = new double(atof((char *)lati));

this->latitude = *latDub;
  1. Мне нужно сохранить широту в переменной экземпляра latitude.

  2. Переменная data представляет собой текстовый файл для чтения.

  3. this->latitude объявлен как double.

Я проверил, и переменная lati является правильным значением, но как только я пытаюсьчтобы преобразовать его в double, значение по какой-то причине меняется на 0.Я специально должен использовать метод atof при конвертации!

Ответы [ 2 ]

2 голосов
/ 19 сентября 2011

(char *)lati не делает то, что вы думаете, что делает.То, что вы явно пытаетесь сделать, это получить последовательность char, связанную с lati, но на самом деле вы просто сжимаете string* в char*, что является всевозможными плохими.

В std :: string есть функция-член, которая даст вам именно то, что вы хотите.Вы должны просмотреть документацию для строки и заменить (char *)lati вызовом этой функции.

0 голосов
/ 19 сентября 2011

Почему ваш код компилируется, но дает бессмысленные результаты, уже было объяснено adpalumbo .В вашем коде есть две фундаментальные проблемы, приводящие к этой ошибке, о которых я хочу рассказать здесь.

Во-первых, вы используете приведение в стиле C: (T)obj.По сути, это просто говорит компилятору замолчать, вы знаете, что делаете.Это редко бывает хорошей идеей, потому что, когда вы знаете, что делаете, вы обычно можете обойтись без таких бросков.

Другое - то, что вы используете объекты, динамически выделяемые в куче.В C ++ объекты должны создаваться в стеке, если у вас нет веских причин для использования динамических объектов.А динамические объекты обычно скрыты внутри объектов в стеке.Таким образом, ваш код должен выглядеть следующим образом:

string lati(data.substr(0, data.find_first_of(",")));
double latDub = /* somehow create double from lati */;
this->latitude = latDub;

Конечно, latDub совершенно не нужен, вы также можете написать прямо в this->latitude.

Теперь обычным способом преобразования строки в какой-либо другой тип является ее потоковая передача через поток строк.После удаления ненужных переменных, которые вы ввели, ваш код будет выглядеть следующим образом:

std::istringstream iss(data.substr(0, data.find_first_of(",")));
if( !iss >> this->latitude ) throw "Dude, you need error handling here!";

Обычно вы хотите упаковать это преобразование из строки в служебную функцию, которую вы можете повторно использовать в коде:

inline double convert3double(const std::string& str)
{
  std::istringstream iss(str);
  double result;
  if( !iss >> result )
    throw std::exception("Dang!");
  return result;
}

Однако, поскольку один и тот же алгоритм может использоваться для всех типов (для которых operator>> значимо перегружен входным потоком в качестве левого операнда), просто сделайте этот шаблон:

template< typename T >
inline T convert3double(const std::string& str)
{
  std::istringstream iss(str);
  T result;               // presumes default constructor
  if( !iss >> result )    // presumes operator>>
    throw std::exception("Dang!");
  return result;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...