Вставлю свои 5 копеек. :) Лично я всегда использовал связку fread + filelength для получения всего файла, а потом выполнял разбор полученного массива байт:
#include <stdio.h>
using namespace std;
list<string> parseFile(const string & filename)
{
list<string> res;
FILE *fid;
fid = fopen(filename.c_str(), "rt");
if(fid = NULL)
return res;/*можно наверно, исключение выкинуть, но когда-то я слышал, что в c++ лучше этого не делать. Возможно, с тех пор все изменилось*/
long size = _filelength(fileno(fid));
char *buf = new char[size+1];/*+1 в конце нужен что бы туда запихнуть нулевой символ.*/
if(size !=fread(buf, 1, size, fid))
return res;/*упс, что-то случилось - количество прочитанных байт меньше размера файла, но такого не должно быть.*/
buf[size] = '\0';/*делаем из массива байт "null-terminated" - строку*/
string str;
str += buf;
delete [] buf;
//Разбиваем данные по символам переноса строки:
return splitStr(str, "\n");
}
list<string> splitStr(string str, const char * delim)
{
list<string> res;
char *ptr;
while( (ptr = strtok((char *)str.c_str()), delim) != NULL)
{
int len = strlen(ptr);
if(len != 0)
{
string str(ptr);
res.push_back();
ptr+=len;
}
ptr++;
}
return res;
}
int main(int, char **)
{
list<string> lines = parseFile("data.txt");
if(lines.size() <= 0)
return -1;
list<list<string>> values;
for(list::iterator it = lines.begin(), it != lines.end; it++)
{
values.push_back(splitStr(*it, " "));
}
////////////
//Тут можно сделать разбор строк в values, используя функции strtol, strtod, strtof - в зависимости от того, что ожидается на входе
////////////
return 0;
}
Решение длинновато, и я его написал по памяти - возможно, копмилироваться не будет, но думаю, смысл понятен. Я умышленно не использовал fscanf, для ввода и распознавания чисел из файла, поскольку на мой взгляд это самая неудобная функция, которая есть в сишной библиотеке. scanf для ввода с консоли - еще куда ни шло, но для ввода из файла... Имхо, проще запомнить, какая функция преобразует строки в числа, нежели запомнить однобуквенные модификаторы, которые использует scanf/fscanf.
PS:
если для олимпиады длинно, то можно ф-ции parseFile и splitStr таскать с собой на флешке. :) Если конечно, это разрешается...
UPD:
исправил кое-какие ошибки в коде (не знаю, все или нет...)