Как преобразовать массив строк в массив с плавающей точкой в c ?

#c #arrays #string #floating-point

#c #массивы #строка #значение с плавающей запятой

Вопрос:

В принципе, я практически ничего не знаю о C и лишь кратко программировал на Visual Basic.

Я хочу, чтобы набор чисел из CSV-файла сохранялся в виде float массива. Вот некоторый код:

 string stropenprice[702];   
float openprice[702];
int x=0;
ifstream myfile ("open.csv");
if (myfile.is_open())
{
  while ( myfile.good() )
  {
    x=x 1;
    getline (myfile,stropenprice[x]);
    openprice[x] = atof(stropenprice[x]);
    ...
  }
  ...
}
  

В любом случае, там говорится:

ошибка C2664: ‘atof’: не удается преобразовать параметр 1 из ‘std::string’ в ‘const char *’

Ответ №1:

Ну, вы должны были бы сказать, atof(stropenprice[x].c_str()) потому что atof() работает только со строками в стиле C, а не с std::string объектами, но этого недостаточно. Вам все равно придется разбить строку на фрагменты, разделенные запятыми. find() и substr() может быть хорошим началом (например, смотрите здесь), хотя, возможно, более общая функция токенизации была бы более элегантной.

Вот функция tokenizer, которую я украл откуда-то так давно, что не могу вспомнить, так что приношу извинения за плагиат:

 std::vector<std::string> tokenize(const std::string amp; str, const std::string amp; delimiters)
{
  std::vector<std::string> tokens;

  // Skip delimiters at beginning.
  std::string::size_type lastPos = str.find_first_not_of(delimiters, 0);
  // Find first "non-delimiter".
  std::string::size_type pos     = str.find_first_of(delimiters, lastPos);

  while (std::string::npos != pos || std::string::npos != lastPos)
  {
    // Found a token, add it to the vector.
    tokens.push_back(str.substr(lastPos, pos - lastPos));
    // Skip delimiters.  Note the "not_of"
    lastPos = str.find_first_not_of(delimiters, pos);
    // Find next "non-delimiter"
    pos = str.find_first_of(delimiters, lastPos);
  }

  return tokens;
}
  

Использование: std::vector<std::string> v = tokenize(line, ","); Теперь используйте std::atof() (или std::strtod() ) для каждой строки в векторе.


Вот предложение, просто чтобы дать вам некоторое представление о том, как обычно пишется такой код на C :

 #include <string>
#include <fstream>
#include <vector>
#include <cstdlib>

// ...

std::vector<double> v;

std::ifstream infile("thefile.txt");
std::string line;

while (std::getline(infile, line))
{
  v.push_back(std::strtod(line.c_str(), NULL));  // or std::atof(line.c_str())
}

// we ended up reading v.size() lines
  

Комментарии:

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

2. @user1040781: Без проблем 🙂 (По-видимому, я получаю уведомления о комментариях к моим собственным сообщениям; в общем, используйте @ синтаксис для создания предупреждения.) Удачи!

3. @user1040781: Пока вы этим занимаетесь, вы могли бы также заменить довольно неуклюжий массив фиксированного размера на vector . Я отредактирую сообщение, чтобы добавить предложение.