fscanf в C (Возврат на одну позицию)

Модератор: Модераторы разделов

gtn-gagarin
Сообщения: 95
ОС: Linux

fscanf в C

Сообщение gtn-gagarin »

Код:

#include <stdlib.h> #include <stdio.h> void main() { FILE *fin; fin = fopen("fin", "r"); float value; float value2; float value3; char newline; char newline2; char back; fscanf(fin, "%f %f%c", &value, &value2, &newline); if(newline=='\n') { printf("ok\n"); }; if(newline==' ') { fscanf(fin, "%c", &newline2); if (newline2=='\n') printf("ok\n"); else { fscanf(fin, "\b"); fscanf(fin, "%f", &value3); printf("%f", value3); } }; fclose(fin); }

Объясняю, что я хотел сказать последним if-else. Если newline2 равна концу строки, то печатается "ok". Если нет, то возвращается назад на один символ и считывает float-переменную value3.
Но вышеуказанная программа не выполняет возврат назад (считывает число начиная со второй цифры).
Можно ли осуществить то что я хочу?
Спасибо сказали:
Аватара пользователя
Liksys
Сообщения: 2910

Re: fscanf в C

Сообщение Liksys »

Потому что тебе надо использовать fseek() для перемещения по файлу. А это какая-то хренотень.
Спасибо сказали:
gtn-gagarin
Сообщения: 95
ОС: Linux

Re: fscanf в C

Сообщение gtn-gagarin »

То, что это хренотень, я уже понял:) Спасибо за подсказку.
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: fscanf в C

Сообщение drBatty »

есть ещё ungetc() она делает именно то, что ты хочешь. Хотя я бы юзал fseek().

Ещё раз повторю(вам не надоело? в подпись поставлю) Нельзя юзать gets(), scanf("%s") и cin>>(char*)
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
Fla
Сообщения: 39
ОС: ArchLinux

Re: fscanf в C

Сообщение Fla »

gtn-gagarin, fseek, он перемещает курсор на выбранную позицию. Давно его не юзал, поэтому расписать не могу.
Спасибо сказали:
Аватара пользователя
uptime
Сообщения: 1661
Статус: Drinker with computing problems
ОС: kubuntu 8.04

Re: fscanf в C

Сообщение uptime »

gtn-gagarin, пересмотрите лучше алгоритм.
Я для таких штук работаю со строками, т.е. читаю строку целиком в буфер и далее с ней можно делать что угодно легко и просто, разбивать на токены и т.п.

успехов
The answer, my friend, is blowin' in the wind.
The answer is blowin' in the wind.
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: fscanf в C

Сообщение drBatty »

uptime писал(а):
25.11.2007 14:57
gtn-gagarin, пересмотрите лучше алгоритм.
Правильно. Но тут можно и схитрить:

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

if(fscanf(fin, "%f %f", &v1, &v2) != 2)
       {//обработка ошибки}
long pos = ftell(fin);
if(fscanf(fin, "%f\n", &v3) == 1)
       //введены 3 числа
else
       {//то-ли ошибка, то-ли нет третьего числа
              fseek(fin, pos);
              if(fgetc(fin) == '\n')
                       //два числа
              else
                       //ошибка
       }
Ну и добавить проверку не ошиблись ли ftell()&fseek() А если всё равно, что будет при ошибке, можно ещё половину кода выкинуть. :)

ЗЫЖ uptime, а ты не задумывался, как ввести float из строки? atof()&sscanf() не подходят, непонятно с какого символа продолжать разбор строки. Т.ч. придётся самому писать const char *atof(const char *, float *)...
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
ssh
Сообщения: 78
ОС: Debian

Re: fscanf в C

Сообщение ssh »

ЗЫЖ uptime, а ты не задумывался, как ввести float из строки? atof()&sscanf() не подходят, непонятно с какого символа продолжать разбор строки. Т.ч. придётся самому писать const char *atof(const char *, float *)...



Примерно так:

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

char *p, string[ 1000 ]
float  first, second, ...;

fscanf( file, "%s", string );  // читаем строку в буфер.

p = strtok( string, ", " );   // предполагая, что числа в строке разделены пробелами или запятыми
first = atof( p );

p = strtok( NULL, ", " );
second = atof( p );

p = strtok( NULL, ", " );
third = atof( p );


И вообще полезно почитать man strtok.
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: fscanf в C

Сообщение drBatty »

ssh писал(а):
25.11.2007 20:05
И вообще полезно почитать man strtok.
Угу. Долго вспоминал, за что я её ненавижу, перечитал man, вспомнил: я два дня из-за неё медетировал, потом таки достиг просветления. Зарёкся больше никогда так не делать. Подумаешь, применил в функции с ней, свою функцию, тоже с нею... Теперь только strpbrk(). Что касается темы, я имел ввиду ввод числа до первого символа невходящего в число, как fscanf, у тебя такие "числа" пройдут: "7аовлат ".
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
ber
Сообщения: 13
ОС: Gentoo

Re: fscanf в C

Сообщение ber »

fseek(fin, -1, SEEK_CUR) - отмотает на 1 байт назад от текущей позиции, если еще надо)

а еще проще, по-моему, это через потоки делать. хотя может вам нельзя
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: fscanf в C

Сообщение drBatty »

ber писал(а):
27.11.2007 00:17
а еще проще, по-моему, это через потоки делать. хотя может вам нельзя
Почему нельзя, давай пример, наверняка многим пригодится.
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
ber
Сообщения: 13
ОС: Gentoo

Re: fscanf в C

Сообщение ber »

Ну, мне кажется, я бы попытался прочесть все данные, а потом смотрел по результатам,
если значение val3 не изменилось - скорее всего 3ег

Код:

ifstream ifile(argv[1]); double val1 = 0, val2 = 0, val3 = 0; char ch; ifile >> val1 >> val2 >> val3;


или можно записать всю строку в буффер с помощью ifile.gets(s); и уже в ней разбираться сколько где чисел
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: fscanf в C

Сообщение drBatty »

ber писал(а):
27.11.2007 19:36
Ну, мне кажется, я бы попытался прочесть все данные, а потом смотрел по результатам,
если значение val3 не изменилось - скорее всего 3ег

Да? А вот и нет, это введёт 3 числа. А если в файле нет чисел оставит val3 без изменения(кстати как ты это узнаешь, может я ноль ввести хочу?). Но по условию числа вводить надо до '\n', а не до конца файла. Без сомнения топик стартер так поначалу и сделал, но - не получилось.
или можно записать всю строку в буффер с помощью ifile.gets(s); и уже в ней разбираться сколько где чисел
Давай пример с std::string...
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
ber
Сообщения: 13
ОС: Gentoo

Re: fscanf в C

Сообщение ber »

Код:

istringstream istr( istringstream::in ); ifstream ifile( argv[1] ); double v1, v2, v3; char str[40]; string st; ifile.getline( str,40 ); istr.str( string(str) ); istr >> v1 >> v2 >> st; if( st != "" ) { istringstream istr1(st,istringstream::in); istr1 >> v3; } cout << v1 << endl << v2 << endl << v3 << endl;


введет, как и у автора либо 3, либо 2 числа, находящиеся на 1ной строке.
Не учитывая довольно нового для меня istringstream, все довольно понятно.
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: fscanf в C

Сообщение drBatty »

ber писал(а):
28.11.2007 00:03
введет, как и у автора либо 3, либо 2 числа, находящиеся на 1ной строке.
Не учитывая довольно нового для меня istringstream, все довольно понятно.
И это топикстартеру не пойдёт, ведь из файла прочитается 40 байт, а ему надо ровно 1 строку. Может просто ifile >> st ?
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
ber
Сообщения: 13
ОС: Gentoo

Re: fscanf в C

Сообщение ber »

ifile >> st загонит в st только 1е слово, т.е. одно число. В принципе можно проверять не изменилась ли строка, но выглядеть будет все более громоздко. Да и вообще - нет предела совершенству)
Спасибо сказали: