Форум «Мир фантастики» — фэнтези, фантастика, конкурсы рассказов

Форум «Мир фантастики» — фэнтези, фантастика, конкурсы рассказов (https://forum.mirf.ru/index.php)
-   Компьютеры и гаджеты (https://forum.mirf.ru/forumdisplay.php?f=35)
-   -   Программирование (https://forum.mirf.ru/showthread.php?t=10348)

SpellCaster 01.11.2010 22:08

Пожалуй, что и так. Я-то читал его уже кое-как зная Си. В принципе можно начинать с любой более-менее популярной книги. Ну а Си изучать лучше, уже имея в запасе знание другого ЯП.

Iron Man 15.11.2010 20:01

Поставил себе Эмбаркодеровскую РЭД студио последнюю) буду заценивать:)

SpellCaster, ты ее сейчас юзаешь?

SpellCaster 15.11.2010 21:16

Если ты про ХЕ, то нет, я на 2010й. ХЕ особо ничем не отличается, а 2010я у нас купленная :)

Iron Man 15.11.2010 21:39

Цитата:

Сообщение от SpellCaster (Сообщение 998780)
Если ты про ХЕ, то нет, я на 2010й. ХЕ особо ничем не отличается, а 2010я у нас купленная :)

Вот эта вот

Iron Man 04.04.2011 18:03

Ламерский вопрос, который почему-то только что пришел мне в голову: кто знает как открепить форму в Embarcadero Rad Studio? То есть, чтобы ее можно было свободно елозить как в Delphi 7?

http://s41.radikal.ru/i091/1104/00/37eb30533ede.png

SpellCaster 05.04.2011 11:13

Как настроить Delphi 2010, чтобы она выглядела как Delphi 7

Gligarr 20.04.2011 21:11

Требуется помощь в нахождении ошибки.
Вкратце объясняю поставленную задачу. Надо создать бинарный файл, внести в него некоторые данные (работа ведется посредством структур), потом открыть его, внести еще данные, и напоследок поработать с даннными из файла (за последнее пока не брался). Всё это надо реализовать с помощью функций.
Скрытый текст - Вот, то что было сделано:
[PHP]#include<stdio.h>
#include<conio.h>
#include<string.h>
#include<math.h>
struct luggage {char name[20]; int number; float weight;}t1;
void create(FILE *); //Создание нового файла
void open(FILE *); //Открытие файла
void add(FILE *); //Добавление в файл
void delete10(FILE *); //Удаление данных о пассажирах с багажом меньше чем 10
main()
{
char c;
FILE *tf;
while(1)
{
puts("1 - New File");
puts("2 - Open File");
puts("3 - Add to File");
puts("4 - Delete info about passengers with weight of luggage less then 10 kilo");
puts("0 - Exit");
c=getch();
switch(c)
{
case'1': create(tf); break;
case'2': open(tf); break;
case'3': add(tf); break;
case'4': delete10(tf); break;
case'0': return 0;
default: puts("Error!");
}
}
}
void create(FILE *tf)
{
char ch;
tf=fopen("lug.dat", "wb");
printf("\n Entering data \n");
do
{
printf("\n Surname: \n");
scanf("%s",t1.name);
printf("\n Number of items: \n");
scanf("%d",t1.number);
printf("\n The total weight of luggage: \n");
scanf("%f",t1.weight);
fwrite(&t1,sizeof(t1),1,tf);
printf("\n Finish? y/n ");
getch();
}
while(ch!='y');
fclose(tf);
}
void open(FILE *tf)
{
int i;
tf=fopen("lug.dat","rb");
i=1;
fread(&t1,sizeof(t1),1,tf);
while(!feof(tf))
{
printf("\n %3d Name %20s with %2d items has %6.2f kilo of luggage \n",i,t1.name,t1.number,t1.weight);
fread(&t1,sizeof(t1),1,tf);
i++;
}
getch();
}
void add(FILE *tf)
{
char ch;
tf=fopen("lug.dat","ab");
printf("\n Entering data \n");
do
{
printf("\n Surname: \n");
scanf("%s",t1.name);
printf("\n Number of items: \n");
scanf("%d",t1.number);
printf("\n The total weight of luggage: \n");
scanf("%f",t1.weight);
fwrite(&t1,sizeof(t1),1,tf);
printf("\n Finish? y/n ");
ch=getch();
}
while(ch!='y');
fclose(tf);
}
void delete10(FILE *tf)
{
//Здесь однажды появится код...
}[/PHP]

И вот теперь о проблеме. При вводе значения веса багажа (или после ввода количества) программа вылетает... Обнаружить косяк в программе не могу, сколько ни пытаюсь. Может кто чего подскажет, где здесь ошибка?

Waterplz 21.04.2011 08:43

Цитата:

while(1)
ололо

не связано с главной проблемой, но
[PHP]void create(FILE *tf)
{
char ch;
...
getch(); // должно быть ch = getch();
//В void open(FILE *tf) даже переменная под это не декларирована
...
while(!feof(tf))
{
printf("\n %3d Name %20s with %2d items has %6.2f kilo of luggage \n",i,t1.name,t1.number,t1.weight);
fread(&t1,sizeof(t1),1,tf);
i++; //должен использоваться для перемешения указателя tf скачками длиной в t1
}[/PHP]

SpellCaster 21.04.2011 10:30

Цитата:

Сообщение от Waterplz (Сообщение 1102997)
ололо

Да ладно, нормальная конструкция
Цитата:

Сообщение от Gligarr (Сообщение 1102825)
При вводе значения веса багажа (или после ввода количества) программа вылетает... Обнаружить косяк в программе не могу, сколько ни пытаюсь

Пошаговая отладка что показывает? На какой строчке вылетает?

Кроме того,
Цитата:

getch();
}
while(ch!='y');
-> тут никак не выйдешь из цикла

Waterplz 21.04.2011 10:35

Цитата:

Пошаговая отладка что показывает? На какой строчке вылетает?
Я так понял что:
Цитата:

При вводе значения веса багажа (или после ввода количества) программа вылетает...

SpellCaster 21.04.2011 13:41

Waterplz, ну, по написанному можно только судить, после каких действий она вылетает, а ведь это не одно и то же.
Если на scanf("%f",t1.weight); - это одно дело, а если на fwrite(&t1,sizeof(t1),1,tf); - другое. Кстати, точно ли нужно &t1, а не *t1? Я уже подзабыл это сишное безумие с указателями/ссылками.
Да, и как она вылетает-то? Вроде как должно быть некое сообщение об ошибке.

Waterplz 21.04.2011 14:17

Цитата:

Кстати, точно ли нужно &t1, а не *t1?
Точно. t1 это структура, &t1 даст адрес этой структуры, что нам и нужно. А *t1 выдал бы содержимое t1, будь t1 указателем.

Gligarr 21.04.2011 15:55

Цитата:

Сообщение от Waterplz (Сообщение 1102997)
 while(!feof(tf)) 
    { 
     printf("\n %3d Name %20s with %2d items has % 6.2f kilo of luggage \n",i,t1.name,t1.number,t1.we ight); 
     fread(&t1,sizeof(t1),1,tf); 
     i++; //должен использоваться для перемешения указателя tf  скачками длиной в t1
    } 

Об этом поподробнее, пожалуйста, ведь по сути операция должна выполнятся верно...

Цитата:

Сообщение от SpellCaster (Сообщение 1103172)
Да, и как она вылетает-то? Вроде как должно быть некое сообщение об ошибке.

Программа сперва зависает, а потом Windows выдает сообщение о том, что программа не отвечает и т.д. и т.п.
А вот с отладкой до сих пор не могу разобраться - использую Dev-C++, а отладчик там какой-то непонятный. Вроде пробегаю по строкам, но вот ничего толком он не выдает...

Так, решил проверить первую функции отдельно:

Скрытый текст - Открытие файла для записи:
[PHP]#include<stdio.h>
#include<conio.h>
#include<math.h>
#include<string.h>
main()
{
struct luggage {char name[20]; int number; float weight;}t1;
char ch;
FILE *tf;
tf=fopen("lug.dat", "wb");
printf("\n Entering data \n");
do
{
printf("\n Surname: \n");
scanf("%s",t1.name);
printf("\n Number of items: \n");
scanf("%d",t1.number);
printf("\n The total weight of luggage: \n");
scanf("%f",t1.weight);
fwrite(&t1,sizeof(t1),1,tf);
printf("\n Finish? y/n ");
ch=getch();
}
while(ch!='y');
fclose(tf);
return 0;
}
[/PHP]


Вылетает уже после ввода веса багажа (Weight), причем во время отладки выдает ошибку "Ваша программа вызвала нарушение доступа (ошибка сегментации)". Подозреваю баг связан со строчкой fwrite(&t1,sizeof(t1),1,tf);

SpellCaster 21.04.2011 16:11

Цитата:

Сообщение от Waterplz (Сообщение 1103200)
t1 это структура, &t1 даст адрес этой структуры, что нам и нужно. А *t1 выдал бы содержимое t1, будь t1 указателем

Не... там же вроде как * и при взятии адреса, и при разыменовании указателя, только местами меняется. А ссылка особняком стоит.

Gligarr, ну ты даешь, блин! Между "Зависает" и "Вылетает" - огромная разница! И разные причины бага.
Тем не менее, всё-таки выясни строчку. Это можно сделать, поставив после каждой строчки вывод чего-нибудь на консоль. Я обычно делаю так (псевдокод):

int step = 0;
...do smth...
writeln(step++);
...do smth...
writeln(step++);
...do smth...
writeln(step++);

- это сразу покажет, на каком моменте затык

Gligarr 21.04.2011 16:28

SpellCaster, попробовал так проверить. Сбой происходит при выполнении команды (!) scanf("%f",t1.weight);
Теперь вот думаю, к чему бы это... Ведь получается программа просто не может по какой-то причине принять ввод значения с клавиатуры...

Upd, всё разобрался, походу нужен имперсант...

Всё, основная программа теперь заработала как надо! Вся ошибка заключалась в том что ввод с клавиатуры уходил по сути "в никуда"... Да, это была глупая ошибка с моей стороны не расставить знак & перед численными значениями из структур)

Waterplz 22.04.2011 10:54

Цитата:

Об этом поподробнее, пожалуйста, ведь по сути операция должна выполнятся верно...
у тебя tf не изменяется. то есть этот цикл у тебя или выполниться 0 раз (при пустом файле), или будет бесконечным.

Gligarr 22.04.2011 19:10

Цитата:

Сообщение от Waterplz (Сообщение 1103919)
то есть этот цикл у тебя или выполниться 0 раз (при пустом файле), или будет бесконечным.

Ну в данной функции у меня программа работает без проблем. Выполнение идёт, так как в процедуре fread прописываются и шаг перехода "sizeof(t1)" и число элементов "1" (то есть одна структура). Поэтому, ошибки здесь, думаю, нет.

А вот здесь почему то не получается удалить структуру... Как раз переходит или в бесконечный цикл, или не даёт нужного эффекта.
Баг происходит после нажатия клавиши "Y", если верить отладчику...
Вообще, как можно организовать удаление определенной структуры?

Скрытый текст - Удаление структур с t1.weight<10:
[PHP]void delete10(FILE *tf)
{
char ch;
int i=0,n=0;
tf=fopen("lug.dat","rb+");
while(!feof(tf))
{
fread(&t1,sizeof(t1),1,tf);
if(t1.weight<10)
{
printf("\n Luggage of %s weighs less then 10. Delete data about %s? y/n \n", t1.name, t1.name);
ch=getch();
if(ch=='y')
{
fseek(tf,-sizeof(t1),SEEK_CUR);
fwrite(&n,1,sizeof(t1),tf);
fclose(tf);
}
}
}
}[/PHP]


По выполнении программы обнуляется (а нужно чтоб удалилась) первая строчка удовлетворяющая заданному условию. А остальные, тоже удовлетворяющие, почему-то остаются без изменений (хотя тоже должны удалиться)...

Вот программа целиком:

Скрытый текст - Программа:
[PHP]#include<stdio.h>
#include<conio.h>
#include<string.h>
#include<math.h>
struct luggage {char name[20]; int number; float weight;}t1;
void create(FILE *);
void open(FILE *);
void add(FILE *);
void delete10(FILE *);
main()
{
char c;
FILE *tf;
while(1)
{
puts("1 - New File");
puts("2 - Open File");
puts("3 - Add to File");
puts("4 - Delete info about passengers with weight of luggage less then 10 kilo");
puts("0 - Exit");
c=getch();
switch(c)
{
case'1': create(tf); break;
case'2': open(tf); break;
case'3': add(tf); break;
case'4': delete10(tf); break;
case'0': return 0;
default: puts("Error!");
}
}
}
void create(FILE *tf)
{
char ch;
tf=fopen("lug.dat", "wb");
printf("\n Entering data \n");
do
{
printf("\n Surname: \n");
scanf("%s",t1.name);
printf("\n Number of items: \n");
scanf("%d",&t1.number);
printf("\n The total weight of luggage: \n");
scanf("%f",&t1.weight);
fwrite(&t1,sizeof(t1),1,tf);
printf("\n Finish? y/n \n");
ch=getch();
}
while(ch!='y');
fclose(tf);
}
void open(FILE *tf)
{
int i;
tf=fopen("lug.dat","rb");
i=1;
fread(&t1,sizeof(t1),1,tf);
while(!feof(tf))
{
printf("\n %3d Name %20s with %2d items has %6.2f kilo of luggage \n",i,t1.name,t1.number,t1.weight);
fread(&t1,sizeof(t1),1,tf);
i++;
}
getch();
}
void add(FILE *tf)
{
char ch;
tf=fopen("lug.dat","ab");
printf("\n Entering data \n");
do
{
printf("\n Surname: \n");
scanf("%s",t1.name);
printf("\n Number of items: \n");
scanf("%d",&t1.number);
printf("\n The total weight of luggage: \n");
scanf("%f",&t1.weight);
fwrite(&t1,sizeof(t1),1,tf);
printf("\n Finish? y/n \n");
ch=getch();
}
while(ch!='y');
fclose(tf);
}
void delete10(FILE *tf)
{
char ch;
int i=0,n=0;
tf=fopen("lug.dat","rb+");
while(!feof(tf))
{
fread(&t1,sizeof(t1),1,tf);
if(t1.weight<10)
{
printf("\n Luggage of %s weighs less then 10. Delete data about %s? y/n \n", t1.name, t1.name);
ch=getch();
if(ch=='y')
{
fseek(tf,-sizeof(t1),SEEK_CUR);
fwrite(&n,1,sizeof(t1),tf);
fclose(tf);
}
}
}
}

[/PHP]

SpellCaster 22.04.2011 22:30

Цитата:

Сообщение от Gligarr (Сообщение 1104095)
Вообще, как можно организовать удаление определенной структуры?

Ууу, брат. Удаление из/добавление в середину в файлах делается только с копированием остального хвоста файла. То есть в случае удаления тебе надо делать так:
1) Прочитать структуру t1
2) Проверить условия, спросить
3) Если удовлетворяет условию, цикл:
* Прочитать следующую структуру t2
* Переместиться на 2*SizeOf(luggage) назад (потому что к этому моменту указатель в файле будет у начала второй структуры после удаляемой t1 - назовем ее t3)
* Записать в текущее место t2
* Переместиться на SizeOf(luggage) вперед
* Повторить цикл
5) В конце обрезать файл на SizeOf(luggage) байт

То есть, проще говоря, по кусочкам "подтащить" структуры, заполнив свободную ячейку в файле

Что же касается твоего кода "Удаление структур с t1.weight<10", то ты там вообще что-то непонятное творишь. В случае утвердительного ответа перезаписываешь структуру, которую надо удалять, причем на ту же позицию, где она и есть в файле, а потом еще и зачем-то закрываешь файл

Sofist 24.07.2011 13:55

Цитата:

Сообщение от SpellCaster (Сообщение 1104280)
То есть, проще говоря, по кусочкам "подтащить" структуры, заполнив свободную ячейку в файле

обсуждение было давно, но предлагаю другой вариант:
1) добавить в структуру поле bool deleted, по умолчанию присваивать false
2) при согласии пользователя на удаление структуры, менять её в true
3) вывод и обработку производить только если !deleted
4) создать отдельную утилитку, которая будет:
4.1) читать структуры исходного файла
4.2) если !deleted записывать их во временный
4.3) по окончании, проверить, что временный файл существует и непуст
4.4) если это так, то переместить исходный файл в архив, а временный переименовать в исходный
5) запускать эту утилитку, скажем, еженедельно

SpellCaster 25.07.2011 14:25

Это всё, конечно, верно, но для случая реального применения. А тут, вроде бы, была лаба.


Текущее время: 09:56. Часовой пояс GMT +3.

Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.