2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




 
 С-программа по считыванию данных из файла
Сообщение11.11.2008, 03:08 
Аватара пользователя
Подскажите, пожалуйста, с помощью какой функции в С можно прочитать числа типа double.

Передо мной стоит такая задача: есть файл данных, где записаны позиции частиц (x, y, z)- по строчкам, все координаты разделены пробелом, всего 3750 частиц = 3750 строчек. Нужно отсортировать по позициям z.

С сортировкой нет проблем, а вот прочитать эти позиции z у меня не получается. Открыть файл я могу, нашла только функцию getc, но она читает по символам, а с функциями gets, fgets какие-то дикие проблемы с синтаксисом.

Я разберусь, мне бы только точно знать, что это та самая функция, которая мне нужна. Наверняка это стандартная, часто возникающая задача. Кто-нибудь может мне помочь? Спасибо.

 
 
 
 
Сообщение11.11.2008, 05:43 
Попробуйте вот такие функции:
Код:
FILE *f;
char buf[100];
double x,y,z;

f = fopen("a.txt", "rt");
fgets(buf, sizeof(buf), f);
sscanf(buf, "%lf%lf%lf", &x,&y,&z);

 
 
 
 
Сообщение11.11.2008, 09:51 
Аватара пользователя
Можно напрямую читать тройки из файла с помощью функции fscanf без копирования в промежуточный буфер.

 
 
 
 
Сообщение16.11.2008, 10:46 
Аватара пользователя
to Yuri Gendelman
Спасибо огромное! Получилось вот что

Код:
FILE *f;
char buf[100];
double x,y,z;
int j;
double k[3750];

f = fopen("a.txt", "rt");
j=1;
while (j<3750) {
    fgets(buf, sizeof(buf), f);
    sscanf(buf, "%lf%lf%lf", &x,&y,&z);
    k[j] = atof (buf);
    j = j++;
}
fclose(f);

Хотелось бы считывать все три числа, а не только первое, но как это реализовать?
atof по-видимому, только до первого встречного пробела работает.

to PAV
Я слышала, с функцией fscanf есть какие-то трудности и не всегда получается
Буду пытаться

 
 
 
 
Сообщение16.11.2008, 10:52 
Аватара пользователя
Таня Тайс в сообщении #158647 писал(а):
j = j++;


Не пишите так. Пишите только
Код:
j++;

или
Код:
++j;

 
 
 
 
Сообщение16.11.2008, 12:18 
Аватара пользователя
Спасибо!
В моей программе вот это
Код:
sscanf(buf, "%1f %1f %1f",&x,&y,&z);
ну совершенно ни к чему! Даже смешно стало... :D

Добавлено спустя 34 минуты 19 секунд:

PAV в сообщении #157323 писал(а):
Можно напрямую читать тройки из файла с помощью функции fscanf без копирования в промежуточный буфер.

Нужно определять (какие-то) классы, да?

Код:
FILE *f;
double x,y,z;

f = fopen("a.txt","rt");

fscanf(f, "%6f %6f %6f", &x,&y,&z);
printf("%2.4f\n",x);

fclose(f);
Не понимаю, почему, но это неправильно...

 
 
 
 
Сообщение16.11.2008, 13:27 
Аватара пользователя
попробуйте вместо %6f вставить %lg

и еще - запоминайте значение, возвращаемое функцией fscanf, и также выводите его на печать. Это количество полей, которые функция сумела успешно прочитать.

 
 
 
 
Сообщение16.11.2008, 14:07 
Аватара пользователя
PAV
Тысяча раз спасибо! Наконец-то всё так, как надо!!! 8-) :libmexmat:

 
 
 
 
Сообщение16.11.2008, 16:19 
Таня Тайс писал(а):
В моей программе вот это
Код:
sscanf(buf, "%1f %1f %1f",&x,&y,&z);
ну совершенно ни к чему! Даже смешно стало... :D

Этот - действительно ни к чему.
А вот эти:
Код:
sscanf(buf, "%lf %lf %lf",&x,&y,&z);
fscanf(f, "%lf %lf %lf",&x,&y,&z);

читают сразу три числа в 3 переменные - x,y,z.
Здесь не 1-единица, а l-маленькое_L - признак "длинного" формата double.

И замечания:
1. Если Вам нужно считать 3750 чисел, то начинайте цикл с j=0;
2. Пользуйтесь оператором for (...;...;...)

 
 
 
 
Сообщение16.11.2008, 16:33 
Аватара пользователя
Теперь понятно :oops:
Ёще вопрос: что могло бы означать сообщение Segmentation fault
после запуска такой (моей хорошей) программы
Код:
#include "stdio.h"
#include "stdlib.h"

main(){
  FILE *pos;
  FILE *vel;

  double x,y,z;
  double k[3750];//z-position
  double u[3750];//x-velocity
  int i,j;

  pos = fopen("bi_DPD_V1.obs","r");

  j = 0;
  while (j < 3750){
    fscanf(pos,"%lf %lf %lf %lf",&i,&x,&y,&z);
    k[j] = z;
    j++;
  }

  fclose(pos);
  printf("%2.5f\n",k[3]);//control


  vel = fopen("all_DPD_V1.obs","r");

  j = 0;
  while (j < 3750){
    fscanf(vel, "%lf %lf %lf %lf",&i,&x,&y,&z);
    u[j] = x;
    j++;
  }

  fclose(vel);
  printf("%2.5f\n",u[3]);

 
}

:cry: Опять проблемы... Вот что значит неуч-самоучка :) Новая проблема состоит в том, что надо открыть два разных файла и считать оттуда числа. С 1-м всё в порядке, всё как Вы и сказали, а у 2-го Segmentation fault или я не вижу чего-то :roll:

 
 
 
 
Сообщение16.11.2008, 16:43 
Таня Тайс в сообщении #158772 писал(а):
Ёще вопрос: что могло бы означать сообщение Segmentation fault
Вы считывате по формату «double» значание целой переменной $i$. Она меньше по размеру, чем записывается при чтении. Скорее всего, при этом портится соседняя переменная $j$ и обращаение к массиву идет сильно за его пределами.

 
 
 
 
Сообщение16.11.2008, 16:48 
Аватара пользователя
вздымщик Цыпа в сообщении #158776 писал(а):
Вы считывате по формату «double» значание целой переменной $i$.

А как это исправить? Как читать целые переменные? И почему у Kernighan, Ritchie об этом не написано?? И где написано?

Спасибо.

 
 
 
 
Сообщение16.11.2008, 16:50 
Таня Тайс в сообщении #158779 писал(а):
Как читать целые переменные?
"%d"

 
 
 
 
Сообщение16.11.2008, 16:56 
Аватара пользователя
вздымщик Цыпа
Вы были правы. Благодарю

 
 
 [ Сообщений: 14 ] 


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group