#c #scanf
#c #scanf
Вопрос:
Я написал код, который считывает квадратную матрицу из файла .dat и вектор из отдельного.файл dat и дополняет два и выполняет исключение гаусса Джордана, чтобы получить расширенную матрицу в форме уменьшенного эшелона строк. Сейчас я пытаюсь сделать его удобным для пользователя и элегантно завершать работу, когда пользовательский ввод бессмыслен. Например, у меня есть проверка, чтобы убедиться, что матрица квадратная и что длина вектора соответствует размеру матрицы. Что я пытаюсь сделать сейчас, так это проверить, есть ли в файлах данных какие-либо символы, которые не являются числами.
Моя попытка: что-то вроде scanf("%lf", )
сработало бы в том смысле, что оно останавливается, когда натыкается на один из этих символов. Проблема в том, что мой ввод не из командной строки. (командная строка на самом деле здесь не вариант, потому что я хочу, чтобы код мог принимать огромную матрицу, которую пользователь не захотел бы сидеть там и вводить в командной строке). Выполнение fscanf("%f", )
сходит с ума, когда сталкивается со строкой. Есть ли что-нибудь вроде scanf, которое просто остановится, но не сойдет с ума, когда встретит букву и т.д.? Если нет, есть ли какие-либо другие предложения?
Комментарии:
1. прочитайте все как строку, проверьте правильность и преобразуйте…
2. Не допускайте сбоя вообще! Любая нормальная программа выполнит проверку на ошибки и просто завершит работу с ошибкой, если она не может работать должным образом. Что касается вашего вопроса, вероятно, проще всего разделить синтаксический анализ, проверку и обработку, и поэтому вы можете просто выйти, если есть ошибка синтаксического анализа или проверки.
3. 1 за » … элегантный сбой … » 🙂 В любом случае, если серьезно, я полностью согласен с тем, что написал Kerrek SB выше! Дополнительно я хотел бы упомянуть о
scanf()
возвратахEOF
после » сойдя с ума «, чтобы вы могли легко перехватить это условие во время выполнения.
Ответ №1:
Используется fgets
для ввода строки в предварительно выделенный буфер, затем strtoX
для извлечения числа с плавающей запятой. ( X
= f
для float
, X
= d
для double
, X
= ld
для long double
. Его сигнатурой является X_t strtoX(const char *nptr, char **endptr)
, где X_t
— соответствующий тип ( float
, double
или long double
).
Пока не будет достигнут конец строки ( **endptr = 'n'
), увеличивайте указатель на строку (который установлен так, чтобы указывать на предварительно выделенный буфер, и если после этого он не увеличивается strtoX
, то увеличивайте его до тех пор, пока это не произойдет. Используйте две переменные, например, так:
char *lp = buf;
char *lp2 = buf;
do {
X_t x = strtoX(lp, amp;lp2);
if (lp == lp2 amp;amp; *lp != 'n') {
lp;
continue;
}
if (*lp2 == 'n')
goto read_line;
// do something with x
} while (1);
Мой код не очень хорош, но он должен показать суть.
Кроме того, strtoX
для X
= f
и X
= ld
не поддерживается до C99 / POSIX 2011.