Из Википедии:
На языке программирования C, статичный используется с глобальными переменными и функциями для установки их объема на содержание файла. В локальных переменных, статичных, используется для хранения переменной в статически выделенной памяти вместо автоматически выделенной памяти. В то время как язык не диктует реализацию ни одного типа памяти, статически выделенная память обычно резервируется в сегменте данных программы во время компиляции, в то время как автоматически выделенная память обычно реализуется как стопка устанавливающегося вызова.
Поскольку это помечено как C ++, наиболее очевидным способом было бы использование потоков. В голове у меня может получиться что-то вроде этого:
std::vector<float> readFile(std::istream& is)
{
char chdummy;
is >> std::ws >> chdummy >> std::ws;
if(!is || chdummy != '*') error();
std::string strdummy;
std::getline(is,strdummy,':');
if(!is || strdummy != "SZA") error();
std::vector<float> result;
for(;;)
{
float number;
if( !is>>number ) break;
result.push_back(number);
}
if( !is.eof() ) error();
return result;
}
Почему float
, BTW? Обычно двойной
намного лучше.
Отредактируйте , так как возник вопрос, является ли возвращение копии вектора
хорошей идеей:
В качестве первого решения я бы определенно сделал очевидное. Функция считывает файл в вектор
, и наиболее очевидная вещь, которую должна сделать функция, - это вернуть свой результат. Приведет ли это к заметному замедлению, зависит от многих вещей (размера вектора, того, как часто и откуда вызывается функция, скорости диска, с которого выполняется чтение, может ли компилятор применять RVO). Я бы не хотел портить очевидное решение оптимизацией, но если профилирование действительно показывает, что это слишком медленно, вектор следует передавать по неконстантной ссылке.
(Также обратите внимание, что C ++ 1x с поддержкой rvalue, который, надеюсь, скоро будет доступен с помощью ближайшего к вам компилятора, сделает это обсуждение спорным, поскольку это предотвратит копирование вектора после возврата из функции.)
Библиотека String Toolkit Library (Strtk) предлагает следующее решение вашей проблемы:
#include <iostream>
#include <string>
#include <deque>
#include <iterator>
#include "strtk.hpp"
int main()
{
std::deque<float> flist;
strtk::for_each_line("file.txt",
[&flist](const std::string& line)
{ strtk::parse(line," ",flist); }
);
std::copy(flist.begin(),flist.end(),
std::ostream_iterator<float>(std::cout,"\t"));
return 0;
}
Дополнительные примеры можно найти в C ++ String Toolkit (StrTk) Tokenizer .
Простое решение с использованием алгоритмов STL:
#include <vector>
#include <iostream>
#include <string>
#include <iterator>
struct data
{
float first; // in case it is required, and assuming it is
// different from the rest
std::vector<float> values;
};
data read_file( std::istream& in )
{
std::string tmp;
data d;
in >> tmp >> tmp >> d.first;
if ( !in ) throw std::runtime_error( "Failed to parse line" );
std::copy( std::istream_iterator<float>( in ), std::istream_iterator<float>(),
std::back_inserter<float>(d.values) );
return data;
}
Если вам действительно нужно использовать массив, вы должны сначала выделить его (динамически или статически, если вы знаете размер), а затем вы можете использовать тот же алгоритм копирования
// parsing the first line would be equivalent
float data[128]; // assuming 128 elements known at compile time
std::copy( std::istream_iterator<float>(is), std::istream_iterator<float>(),
data );
Но я бы рекомендовал использовать std :: vector даже в этом случае, если вам нужно передать данные в функцию, которая принимает массив, вы всегда можете передать его как указатель на первый элемент:
void f( float* data, int size );
int main()
{
std::vector<float> v; // and populate
f( &v[0], v.size() ); // memory is guaranteed to be contiguous
}
Я бы сделал что-то вроде этого:
std::ifstream input("input.txt");
std::vector<float> floats;
std::string header;
std::getline(input, header); // read in the "* SZA: 10.00" line
if(header_is_correct(header)) {
float value;
// while we could successfully read in a float from the file...
while(input >> value) {
// store it in the vector.
floats.push_back(value);
}
}
ПРИМЕЧАНИЕ: header_is_correct (header)
- это просто пример, вам нужно будет выполнить проверку ошибок для этой первой строки вручную там.