Избавление от строк в файле данных

#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.