2014 dxdy logo

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

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




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


19/03/07
597
Bielefeld
Подскажите, пожалуйста, с помощью какой функции в С можно прочитать числа типа double.

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

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

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

 Профиль  
                  
 
 
Сообщение11.11.2008, 05:43 
Заслуженный участник


15/05/05
3445
USA
Попробуйте вот такие функции:
Код:
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 
Супермодератор
Аватара пользователя


29/07/05
8248
Москва
Можно напрямую читать тройки из файла с помощью функции fscanf без копирования в промежуточный буфер.

 Профиль  
                  
 
 
Сообщение16.11.2008, 10:46 
Аватара пользователя


19/03/07
597
Bielefeld
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 
Супермодератор
Аватара пользователя


29/07/05
8248
Москва
Таня Тайс в сообщении #158647 писал(а):
j = j++;


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

или
Код:
++j;

 Профиль  
                  
 
 
Сообщение16.11.2008, 12:18 
Аватара пользователя


19/03/07
597
Bielefeld
Спасибо!
В моей программе вот это
Код:
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 
Супермодератор
Аватара пользователя


29/07/05
8248
Москва
попробуйте вместо %6f вставить %lg

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

 Профиль  
                  
 
 
Сообщение16.11.2008, 14:07 
Аватара пользователя


19/03/07
597
Bielefeld
PAV
Тысяча раз спасибо! Наконец-то всё так, как надо!!! 8-) :libmexmat:

 Профиль  
                  
 
 
Сообщение16.11.2008, 16:19 
Заслуженный участник


15/05/05
3445
USA
Таня Тайс писал(а):
В моей программе вот это
Код:
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 
Аватара пользователя


19/03/07
597
Bielefeld
Теперь понятно :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 


12/09/08

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

 Профиль  
                  
 
 
Сообщение16.11.2008, 16:48 
Аватара пользователя


19/03/07
597
Bielefeld
вздымщик Цыпа в сообщении #158776 писал(а):
Вы считывате по формату «double» значание целой переменной $i$.

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

Спасибо.

 Профиль  
                  
 
 
Сообщение16.11.2008, 16:50 


12/09/08

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

 Профиль  
                  
 
 
Сообщение16.11.2008, 16:56 
Аватара пользователя


19/03/07
597
Bielefeld
вздымщик Цыпа
Вы были правы. Благодарю

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 14 ] 

Модераторы: Karan, Toucan, PAV, maxal, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group