Страница 1 из 1

Форматный ввод на C++

Добавлено: 06 апр 2017, 10:43
Павел Легков
Джентльмены, всем доброго времени суток!
У меня вопрос по форматному вводу C++.
Задача следующая – нужно читать исходные данные (числа) из текстового файла древнего формата.
Каждое число записано в поле длиной восемь символов, т.е. строка файла представляет собой нечто следующее:
123 34.78 54.123 и т.п.
Проблема в том, что число может занимать все восемь символов, и тогда между соседними числами не будет пробелов. Для Fortrana здесь проблем нет, такой формат можно читать стандартными фортрановскими средствами без применения специальных ухищрений. А для C++ я не придумал ничего лучшего, чем:
чтение строки из файла целиком,
принудительная вставка пробелов между полями в прочитанную строку,
создание входного строкового потока на основе полученной строки,
и только после этого чтение чисел из указанного входного строкового потока .
Не подскажете, может быть есть способ попроще, не прибегаю к ухищрениям?
С уважением, Павел.

Re: Форматный ввод на C++

Добавлено: 06 апр 2017, 10:58
Romeo
Ну можно копировать в цикле по 8 символов в отдельный буфер, и потом преобразовывать из него в число. Наверное проще будет выглядеть код. Но в любом случае так, чтобы прочитать все числа одним махом из подобной хитрой строки, не меняя её, никак не получится.

Re: Форматный ввод на C++

Добавлено: 06 апр 2017, 18:28
Павел Легков
Большое спасибо!

Re: Форматный ввод на C++

Добавлено: 06 апр 2017, 18:57
Romeo
Можно даже в том же самом буфере всё делать.

Код: Выделить всё

char buff[256];
scanf("%s", buff);

auto curr = buff;
while (*curr != '\0')
{
   auto next = curr + 8;
   auto old = *next;
   *next = '\0';

   float value = .0;
   sscanf(curr, "%f", &value);
   printf("%f ", value);

   *next = old;
   curr = next;
}
P.S. Пример кода намеренно написан в С-style, так как работа напрямую с памятью там более лаконична.

Re: Форматный ввод на C++

Добавлено: 07 апр 2017, 13:20
Skwoogey
Еще можно резать строку этой функцией, а потом парсить этой.

Re: Форматный ввод на C++

Добавлено: 07 апр 2017, 17:42
Romeo
Нет, резать strtok не получится. У нас нет делиметра. Числа могут быть "слипнуты" :)

Re: Форматный ввод на C++

Добавлено: 10 апр 2017, 00:41
Skwoogey
Кстати, а fcnanf не получится?

Код: Выделить всё

fscnaf(file, "%8f", a);

Re: Форматный ввод на C++

Добавлено: 10 апр 2017, 16:20
Romeo
Да, чёрт побери, работает :)

Код: Выделить всё

char buff[256];
float value = .0;

scanf("%s", buff);
 
for (auto curr = buff; *curr != '\0'; curr += 8)
{
   sscanf(curr, "%8f", &value);
   printf("%f ", value);
}

Re: Форматный ввод на C++

Добавлено: 10 апр 2017, 20:17
Skwoogey
а с std::cout есть такой же быстрый и эффективный способ форматирования текста, как с printf? Гугл мне выдавал только, что-то неудобное, по типу setw(), setfill().

Re: Форматный ввод на C++

Добавлено: 11 апр 2017, 12:01
Romeo
Точно такого же нет. Это делается через упомянутые манипуляторы и, в общем-то, запись получается тоже достаточно лаконичной.