#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
. Я отредактирую сообщение, чтобы добавить предложение.