ВОПРОС · Q&A

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

3 ответов 4,1 тыс.
AI-выжимка обсуждения скоро

Краткие тезисы обсуждения со ссылками на ключевые ответы появятся здесь.

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

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

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

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


<!--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]
 
Нашёл ошибку в одной букве. :sorry:
 
Статус
Закрыто для дальнейших ответов.