Задача: Типозированное файловое чтение/запись, структуры, типы

  • Автор темы vani2
  • Дата начала
Статус
Закрыто для дальнейших ответов.
V

vani2

#1
Необходимо реализовать программу на языке С(ANSI), которая фильтрует записи некоторого
файла, передаваемого как параметр программы. Результат фильтрации исходного файла
записываются в файл с именем - res.txt.
Записи результата должны быть отсортированы с использованием наперед заданного
алгоритма сортировки. Используемый в задании алгоритм сортировки определяется
вариантом задания.
Исходный файл с данными формально представляет собой матрицу размера mЧn , где
m - строки матрицы (число записей файла), n - число столбцов матрицы (поля записи,
разделенные символом форматирования).m,n наперед неизвестны.
Поля записи разделены ";",строки "\n".
Значение элементов матрицы может быть трех типов:
1. Целое.
2. Вещественное.
3. Строка символов(могут быть пробелы).
Фильтрация осуществляется по одному столбцу по условию <,> или =.
Например:FIELD:1 > 0(по первому полю)

Основные операции должны быть разнесены по отдельным функциям.
Так же должно быть реализовано динамическое распределение памяти.
В оперативной памяти исходный файл должен храниться в виде структуры.

Вот текст моей программы, она еще не полная, в ней полно ошибок и недостающих функций.
Основной мой вопрос: как считать из файла информацию в структуру, чтобы было пригодно затем фильтровать, сортировать данные. Сделал структуру из 3х типов с адресом последующей. Но не приложу ума, как после этого в нормальном порядке, а не с конца, анализировать файл и фильтровать его.Или стоит использовать лругую структуру?
Сохранение и сортировку представляю как делать.
Компилирую на gcc.
Жду любых предложений,вопросов по заданию. Надеюсь вы мне поможете. Заранее спасибо.
 

DarkKnight

Well-known member
01.08.2010
653
0
#2
vani2 , пожалуйста теперь задание объясните своими словами...
А так же именно то в чем у Вас возникла загвоздка, если получу разъяснение помогу вам в решении в ближайшие 2 дня...
Надеюсь вы мне поможете. Заранее спасибо.
Обязательно поможем, главное что бы вы в этом содействовали...
 
V

vani2

#3
Дана таблица неизвестных размеров и типов данных.
Нужно отфильтровать по вводимому полю и критерию.

Вот мой код. Всё работает, только отказывается правильно сохранять последний элемент в строке таблицы. Считывается он правильно(проверял трассировкой).
Помогите, пожалуйста, разобраться.


<!--shcode--><pre><code class='c'>#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

struct itabl {
int cl,fl;
double dr;
char *sim;};

struct tablic { struct itabl tabl;
struct tablic *next,*prev;
char t; };
struct tablic *start=NULL,*mstart,*tmp1=NULL,*tmp2=NULL,*tmp3=NULL,*tmp=NULL;

int read(char*,int,char,char*);
int krit(char *);
int filter(struct tablic *,int,char,char*);
int write(struct tablic *);
FILE *d,*r;

main(int argc, char *argv[]){
char fname[20];
strcpy(fname,argv[1]);
r=fopen("res.txt","w");
krit(fname);
if (fclose(r)) {
printf("Save error\n");
exit(0);}
else printf("Saving...\n");
return 0;
}

int krit(char *fname) {
int f,i=0,n=0,j;
char z,k[20],str[50],field[3];
if ((d=fopen(fname,"r"))==NULL) {
printf("Open error\n");
exit(0); }
else printf("Reading...\n");
printf("Enter the filter:\nFIELD: ");
gets(str);
while (str!=' '){
field=str;
++i;}
f=atoi(field);
z=str[++i];
for (j=i+1;j<strlen(str);j++){
k[n]=str[j];
++n;}
read(fname,f,z,k);
return 0;
}

int read(char *fname,int f,char z,char *k) {
int flag=0,i=0,j,n,p=0;
char c,*s;
d=fopen(fname,"r");
if (!(tmp1=(struct tablic*)malloc(sizeof(struct tablic)))) {
printf("No memory\n");
exit(0); }
if (!(tmp2=(struct tablic*)malloc(sizeof(struct tablic)))) {
printf("No memory\n");
exit(0); }
start=tmp1;
tmp1->prev=NULL;
mstart=tmp1;
while (c!=EOF) {
c=fgetc(d);
if (c!=EOF){
i=p=0;
if (c=='\x0A') {
tmp2->t='\x0A';
c=fgetc(d);}
while (c!='\x3B') { //считывание поля в буфер
*(s+i)=(char*)malloc(sizeof(char));
s=c;
i++;
c=fgetc(d);}
*(s+i)=(char*)malloc(sizeof(char));
s='\0'; //завершаем строку буфера
for (j=0;j<strlen(s);j++)
if ((s[j]>='0')&&(s[j]<='9')||(s[j]=='.')) p++;
if ((p>=(strlen(s)-1))&& isdigit(s[0])) { //Проверка на тип данных и заполнение структуры
for (j=0;j<strlen(s);j++) {
if (s[j]=='.') {
tmp1->tabl.dr=atof(s);
tmp1->tabl.fl=2;
flag=1;}}
if (flag==0) {
tmp1->tabl.cl=atoi(s);
tmp1->tabl.fl=1;}}
else {
tmp1->tabl.sim=(char*)malloc(sizeof(char));
strcpy(tmp1->tabl.sim,s);
tmp1->tabl.fl=3;}
free(s); //очистка переменной буфера
if (tmp2->t=='\x0A') {
filter(mstart,f,z,k);
mstart=tmp1;}
tmp2=tmp1;
if (!(tmp1=(struct tablic*)malloc(sizeof(struct tablic)))) {
printf("No memory\n");
exit(0);}
tmp2->next=tmp1;
tmp1->prev=tmp2;}
else {
tmp1->prev->t=EOF;
filter(mstart,f,z,k);}}
return 0;
}

int filter(struct tablic *mstart,int f,char z,char *k){
int i;
tmp=mstart;
for (i=0;i<(f-1);i++) tmp=tmp->next;
if ((tmp->tabl.fl)!=3) {
if (tmp->tabl.fl==1){ // Для целых
if (z=='=') {
if (tmp->tabl.cl==atoi(k)) write(mstart);}
else if (z=='<') {
if ((tmp->tabl.cl)<atoi(k)) write(mstart);}
else if ((tmp->tabl.cl)>atoi(k)) write(mstart);}
else if (tmp->tabl.fl==2){ //Для дробных
if (z=='='){
if (tmp->tabl.dr==atof(k)) write(mstart);}
else if (z=='<') {
if ((tmp->tabl.dr)<atof(k)) write(mstart);}
else if ((tmp->tabl.dr)>atof(k)) write(mstart);}}
else { //Для строки
if (z=='=') {
if (strcmp(tmp->tabl.sim,k)==0) write(mstart);}
else if (z=='<') {
if (strcmp(tmp->tabl.sim,k)<0) write(mstart);}
else if (strcmp(tmp->tabl.sim,k)>0) write(mstart);}
return 0;
}

int write(struct tablic *mstart) {
tmp=mstart;
while (((tmp->t)!='\x0A')&&((tmp->t)!=EOF)){
if ((tmp->tabl.fl)!=3){
if ((tmp->tabl.fl)==1) fprintf(r,"%d;",tmp->tabl.cl); // Для целых
else fprintf(r,"%f;",tmp->tabl.dr);} //Для дробных
else fprintf(r,"%s;",tmp->tabl.sim); //Для строки
tmp=tmp->next;}
//вот тут выводил последний элемент на консоль правильно
if ((tmp->tabl.fl)!=3){ //Для последней записи, чтобы перейти на новую строку
if ((tmp->tabl.fl)==1) fprintf(r,"%d;\n",tmp->tabl.cl); //Для целых
else fprintf(r,"%f;\n",tmp->tabl.dr);} //Для дробных
else fprintf(r,"%s;\n",tmp->tabl.sim); //Для строки
return 0;
}[/CODE]
 
Статус
Закрыто для дальнейших ответов.