Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Программирование и базы данных (http://forum.oszone.net/forumdisplay.php?f=21)
-   -   Функция ограничения занятости памяти - С (http://forum.oszone.net/showthread.php?t=30011)

Ginger 25-01-2004 16:05 206688

Пишу прогу на С.
в неё входит создание маленькой БД.
использую arrays of records and files
как я не крутила так и не нашла способа не задавать явное колличество записей в БД. т.е. что бы файл растягивался как резиновый по мере поплнения бд или удаления из неё записей.
подумала о том чтобы за ранее обозначить бОльшее число записей в array, допустим сразу 1000, и пополнять по мере необходимости.
но тогда в памяти и будет занимать место для всей 1000 даже если там всего 10 записей.
слышала есть спец. функция, которая ограничивает занятость памяти для array на колличество заполненных ентри. т.е. даже если арей на 1000, а занято всего 10, то память будет занимать только под 10.

подскажите что за функция? желательно с синтаксисом, плз.

[s]Исправлено: Ginger, 16:25 25-01-2004[/s]

Ginger 25-01-2004 18:23 206689

нашла, кажется, выход с безразмерными structures:

Код:

#include <stdio.h>
 
/* random record description - could be anything */ *
struct rec *
{ * * * *
 * *int x,y,z; *
};
 
/* writes and then reads 10 arbitrary records from the file "junk". */
void main() *
{ * *
 * *int i; * *
 * *FILE *f; * *
 * *struct rec r;
 * *
 * */* create the file of 10 records */ * *
 * *f=fopen("junk","w"); * *
 * *for (i=1;i<=10; i++) * *
 * *{ * * *
 * * * *r.x=i; * * *
 * * * *fwrite(&r,sizeof(struct rec),1,f); * *
 * *} * *
 * *fclose(f);
}

так. мне ясно до fwrite(&r,sizeof(struct rec),
а это что такое - 1,f); ?

[s]Исправлено: Ginger, 18:24 25-01-2004[/s]

ivank 25-01-2004 20:17 206690

Ginger
Причём тут безразмерные структуры не ясно. Обычный RANDOM access к файлу.

Если всё хранится в файле, то вполне подойдёт связка fseek/ftell. Если надо запись надо удалить, то просто помечаешь её как удалённую (т.к. сдвигать все последующие слишком долго). И изредка сжимаешь БД сдвигая все записи на места удалённых. Так работают некоторые dbm-базы. Правда, там ещё поле-ключ поддерживается, но это детали. Там просто балансируемое при доступе дерево с ключами в начале файла в простейшем случае сойдёт.

На счёт fwrite:
Цитата:

size_t fwrite( const void *buffer, size_t size, size_t count, FILE *stream );
Parameters

buffer
 Pointer to data to be written
size
 Item size in bytes
count
 Maximum number of items to be written
stream
 Pointer to FILE structure
Добавлено:

RANDOM д.б. написано маленькими буквами, а безразмерных структур вообще не существует.

Ginger 25-01-2004 22:03 206691

говоря о размере я имела ввиду функцию - sizeof()
о fwrite() спросила, потому что не знаю синтаксиса, а не потому что считаю, что она как-то на размер файла влияет

и это всё не главное. мой главный вопрос в первом посте:
Цитата:

подскажите что за функция? желательно с синтаксисом, плз.
Цитата:

а безразмерных структур вообще не существует.
вот про это и спич.

ivank 25-01-2004 23:24 206692

Какое имеет отношение sizeof к безразмерности не ясно.

Начнём с простого вопроса: хранится вся информация в файле или в памяти? В оригинальном посте это не очевидно (мне во всяком случае). А так же, храниться должно всё именно как массив (т.е. в программе присутствует доступ по индексу) или как угодно/удобно?

Если в файле, то см. предыдущий мой ответ. Т.е. надо курить доументацию поблочному вводу выводу, а так же ф-иям установки/чтения позиции в файле. Весь необходимый арсенал ф-ий в этом случае: fopen, fclose, fwrite, freed, fseek, ftell.

Далее, если мы пользуем C++ и всё хранится в памяти, то вполне подойдёт stdd:vector/std::deque (в случае массива) или std::list (если присутствует только последовательный доступ к элементам).

Если мы пользуем чистый C, то есть ф-ии malloc/free/realloc. В частности, интересна ф-ия realloc, которая изменяет размер памяти выделенной с помощью malloc.

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

В общем, если чуть поточнее будут поставлены условия, то любой из этих способов можно будет рассмотреть поподробнее.

Ginger 25-01-2004 23:54 206693

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

так вот я и думаю, как это дело организовать по умному.

Цитата:

Если мы пользуем чистый C, то есть ф-ии malloc/free/realloc. В частности, интересна ф-ия realloc, которая изменяет размер памяти выделенной с помощью malloc.
это я тоже нашла, но одно НО - нам этого не давали. нам файлы-то 2 дня назад без особого углубления дали. поэтому могут счесть за ненужные усложнения.

я тут порылась и придумала приблизительно такой выход:
для каждой категории заводим отдельный файл
имя продукта и его каллорийность записываем через строку, т.е:
белый хлеб
226
чёрный хлеб
214
...

когда нам нужно мы находим (юзер будет вводить имя продукта, а прога находить его каллорийность и вычеслять что там надо) каллорийность переводим его из чар в инт (т.к. я не знаю как хранить каллорийность как инт):
callor=(int)value_of_caloricity
(вроде так можно)
и делаем вычесления.

конечно был ещё "выход":
создать struct { char name[40]; int caloricity;} для каждой категории..
при этом записей должно быть какое-то колличество, т.е. arrays of records
вот я с самого начала и спросила - есть ли функция ограничения занятости памяти до заполненного коллическва ентриес в аррей...
но это ещё ладно, а вот как это дело запихать в файл и как потом от туда так же считать...  я не знаю...

[s]Исправлено: Ginger, 0:38 26-01-2004[/s]

Ginger 26-01-2004 16:58 206694

ну обьясните хотя бы как struct Vegetables { char name[40]; int caloricity;} записать в файл, а потом из файла преобразовать в struct при чтении? чтобы int caloricity можно было пользоваться при вычеслении.

ivank 26-01-2004 18:32 206695

Ginger
Если сойдёт бинарный вид, то fwrite(&data, sizeof(data), 1, out);

В общем, неправильный, но наименее требовательный к знаниям способ. Данные хранятся в файле data.dat

Добавление записи.
Код:

out = fopen("data.fat", "a");
fseek(out, 0, SEEK_END);
fwrite(&data, sizeof(data), 1, out);
fclose(out);

Удаление записи с заданным индексом index (индексация с единицы), с уплотнением.
Код:

int n, i, desc;

out = fopen("data.fat", "a+");
fseek(out, 0, SEEK_END);
count = ftell(out) / sizeof(data);
for (i = index; i < n; ++i)
{
    fseek(out, i*sizeof(data), SEEK_SET);
    fread(&data, sizeof(data), 1, out);
    fseek(out, (i-1)*sizeof(data), SEEK_SET);
    fwrite(&data, sizeof(data), 1, out);
}
fclose(out);

// некошерно, и не уверен что будет стопудово работать:
// не люблю работу с дескрипторами вообще.
desc = _open("data.dat", _O_RDWR | _O_RANDOM);
_chsize(desc, sizeof(data)*(n-1));
_close(desc);

Как считать, надеюсь понятно (хинт: fread, feof)

Ginger 28-01-2004 21:19 206696

ivank
вобщем в твоём примере я мало чего поняла...
но нашла хорошую книжку, где чуть ли не каждая буковка расталковывается, там прочитала о нужных мне функциях и вот что получилось (без malloc(), fseek(), ftell() etc...)

Код:

#include <stdio.h>
/* Proga pishit i chitaet dlia odnogo kataloga */

#define FALSE 0
#define TRUE !FALSE

struct vegetables
{
   char name[40];
   int caloricity;
}veg;

void write_info(void);
void read_info(void);

int main(void)
{
   char c;
   int done=FALSE;
       
   while(!done)
   {
        puts("\n            ***:: Vegatables Catalogue ::***\n");
                puts("  A - Add new entry\n");
                puts("  L - List entries\n");
                puts("  Q - Quit\n");
                printf("  Your choice is: ");
               
                c = getch();
                c = tolower(c);
               
                switch(c)
                {
                        case('a'):
                            puts("     Add new entry\n");
                            write_info();
                            break;
                        case('l'):
                            puts("     List all entries\n");
                            read_info();
                            break;
                        case('q'):
                            puts("    Quit\n");
                            done=TRUE;
                            break;
                               default:
                                    puts("    Incorrect letter. Try again.");
                                    done=FALSE;
                                    break;
                }
        }       
}

void write_info(void)
{
        FILE *veget;
        int calor;
       
        printf("Enter product name: ");
        gets(veg.name);
        printf("Enter its caloricity per 100g: ");
        veg.caloricity = scanf("%i",&calor);
       
        veget = fopen("G:/Studies/Project/programm/vegetables.dat", "a");
       
        if(!veget)
        {
                puts("Error openning file");
                exit(1);
        }
        else
        {
                fwrite(&veg,sizeof(veg),1,veget);
        }
       
        fclose(veget);
        puts("Entry added");
}

void read_info(void)
{
        FILE *veget;
        int x;  
       
        veget = fopen("G:/Studies/Project/programm/vegetables.dat", "r");
       
        if(!veget)
        {
                puts("Error reading file");
                return;
        }
        else
        {
                while(TRUE)
                {
                        x=fread(&veg,sizeof(veg),1,veget);
                       
                        if(!x) break;
                       
                        printf("\nProduct Name: %s\n",veg.name);
                        printf("Its caloricity: %i\n",veg.caloricity);
                }
        }
        fclose(veget);       
}


ivank 29-01-2004 01:30 206697

Ginger
В общем-то добавление и чтение сделаны как я и сказал :)
А удаления нет вообще.

Кстати, ещё более простой метод удаления, я о нём забыл в предыдущий раз сказать, хотя хотел: открываем файл с данными для чтения, и временный для записи. Затем в цикле копируем все записи кроме той, которую надо удалить, из исходного файла во временный. Закрываем оба файла, и таким же маром копируем всё из временного в файл с данными. Дёшево и сердито.

Добавлено:

Цитата:

veg.caloricity = scanf("%d",&calor);
Должно быть veg.scanf("%i",&veg.caloricity); наверно.

Ginger 29-01-2004 02:14 206698

ivank
Цитата:

В общем-то добавление и чтение сделаны как я и сказал
я вобще мало поняла, что ты сказал...

Цитата:

Кстати, ещё более простой метод удаления
а можно не перекидывать всё опять, а переименовать файлы. старый в bak а новый в его имя.
нужно попробовать.

Цитата:

Должно быть veg.scanf("%i",&veg.caloricity); наверно
ой, наверно! после того как запостила, обнаружила, что он мне вместо якобы вводимых 345, к примеру, выдаёт 1.
отркыла файл, посмотрела - там и записан 1. значит читает не верно. короче покрутила, повертела не поняла, как сделать (примера ни одного не нашла) и сделал через float. :gigi:
надо твой вариант попробовать! только выглядит как в object oriented...

а как редактирование осуществить?

Добавлено:

вобщем не
Цитата:

veg.scanf("%i",&veg.caloricity);
а scanf("%i",&veg.caloricity); и всё ок стало!


[s]Исправлено: Ginger, 2:22 29-01-2004[/s]

ivank 29-01-2004 03:04 206699

[rus]Ya prosto ochepyatalsya, kogda kopiroval. Vernee nedoudalyal nemnogo. Koroche, kak vsegada oblazhalsya.

P.S. Na schet ne ponyala - est' u menya takoi porok, zaumnyami slovami pol'zovat'sya :([/rus]

Ginger 29-01-2004 17:29 206700

всё равно меня на мысль правильную наталкнул. ;)

сталкнулась с ещё одно проблемой:
я сделала меню выбора всех каталогов по принципу меню вверху:
Код:

while(!done)
{
puts("\n * * * ****:: Caloricity Calculation Program - Caloricity Tables ::***\n\n");
puts(" *Please, select catalogue:\n");
puts(" *B - Bread and Macarony * * * * *V - Vegetables\n");
puts(" *F - Fruits and Berries * * * * *M - Meat Products\n");
puts(" *S - Fish Products * * * * * * * L - Milk Products\n");
puts(" *A - Fat * * * * * * * * * * * * O - Other\n");
puts(" *Q - Quit\n");
printf(" * * * * Please, enter relevant letter: ");

c = getch();
c = tolower(c);

switch(c)
{
case('b'):
 * * puts(" Bread and Macarony\n");
 * * add_del_dis();
 * * break;
case('v'):
 * * puts(" Vegetables\n");
 * * add_del_dis();
 * * break;
case('f'):
 * * puts(" Fruits and Berries\n");
 * * add_del_dis();
 * * break;
case('m'):
 * * puts(" Meat Products\n");
 * * add_del_dis();
 * * break;
case('s'):
 * * puts(" Fish Products\n");
 * * add_del_dis();
 * * break;
case('l'):
 * * puts(" Milk Products\n");
 * * add_del_dis();
 * * break;
case('a'):
 * * puts(" Fat\n");
 * * add_del_dis();
 * * break;
case('o'):
 * * puts(" Other\n");
 * * add_del_dis();
 * * break;
case('q'):
 * * puts(" Quit\n");
 * * done=TRUE;
 * * break;
default:
 * * * *puts(" Incorrect letter. Try again.\n");
 * * * *done=FALSE;
 * * * *break;
}
}
}

add_del_dis() функция должна вызывать меню:

Код:

void add_del_dis(void)
{
while(!done)
{
printf("\n * * * * * ****:: Vegetables Catalogue ::***\n\n");
puts(" *A - Add new entry \n");
puts(" *L - List all entries \n");
puts(" *Q - Quit \n");
printf(" *Please, enter relevant letter: ");

c = getch();
c = tolower(c);

switch(c)
{
case('a'):
 * * puts(" Add new entry\n");
 * * write_info();
 * * break;
case('l'):
 * * puts(" List all entries\n");
 * * read_info();
 * * break;
case('q'):
 * * puts(" Quit\n");
 * * return;
 * * break;
default:
 * * * *puts(" Incorrect letter. Try again.\n");
 * * * *done=FALSE;
 * * * *break;
}
}
}

функции write_info() и read_info(), как я писала выше, пишут/читают файл:
veget = fopen("G:/Studies/Project/programm/vegetables.dat", "w");

загвоздка в том что я хочу сначала из главного меню передать в функцию add_del_dis() название каталога соответствующее выбору юзера. т.е. когда юзер на главном меню выбирает Bread and Macarony, то в названии оно и пишеться:
Bread and Macarony Catalogue
- на самом деле это просто передача стрингового значения в функицю add_del_dis() при выборе каталога на главном меню,
что-то типа:
add_del_dis(char *catalogue_name)

потом я хочу чтобы таким же образом в функиции write_info() и read_info(), тоже стринговым значением и тоже с главного меню передавался путь и имя открываемого файла. т.е. когда юзер выбирает Meat products в фукнцию write_info(), если она вызывается передавался:
G:/Studies/Project/programm/meat.dat
а не
G:/Studies/Project/programm/bread_and_mac.dat

только нам никто никогда не обьяснял как обозначать и передавать параметры из функции в функцию. как это сделать?

[s]Исправлено: Ginger, 17:29 29-01-2004[/s]

ivank 29-01-2004 18:17 206701

Код:

switch(c)
{
case 'b':
    puts(" Bread and Macarony\n");
    add_del_dis("path_to_macarony_data");
    break;
// ...
}

Код:

void add_del_dis(char *datafile)
{
    // ...
    c = tolower(getch());
    switch(c)
    {
    case 'a':
        puts(" Add new entry\n");
        write_info(datafile);
        break;
    // ...
    }
}

Код:

void write_info(char *datafile)
{
    // ...
    veget = fopen(datafile, "a");
    // ...
}

И всё остальное по аналогии.

Ginger 29-01-2004 18:44 206702

ivank
Цитата:

add_del_dis("path_to_macarony_data");
Цитата:

void add_del_dis(char *datafile)
я так пыталась. компилер ругался что поинтеры не задефайнены, стринги тоже и не пошла бы я... :(
я же написала, что не знаю как их прописать вначале проги.

у меня они прописаны как:
#include <stdio.h>
#include <conio.h>
#include <ctype.h>
#include <stdlib.h>

#define FALSE 0
#define TRUE !FALSE

void add_del_dis(void); *// но тут в скобках что-то другое должно быть
void write_info(void);
void read_info(void);

struct caloricity_table
{
char name[30];
int caloricity;
}tab;

char c;
int done=FALSE;

// и к тому же стринги, которые передаю, тоже где-то как-то прописать надо.
я не знаю синтаксиса.


оказалось ничего сложного :)
void add_del_dis(char *datafile);
void write_info(char *datafile);
void read_info(char *datafile);

пасиб, ivank

[s]Исправлено: Ginger, 21:39 29-01-2004[/s]

Ginger 30-01-2004 19:57 206703

ivank
написала функцию удаления записей:
Код:

void delete_info(void)  //function deleting form file
{
        FILE *fp;
        FILE *temp;
        char input[30];
        int x;
       
        printf("  Please, enter product NAME: ");
        gets(input);
       
        fp = fopen("G:/Studies/Project/programm/test.dat", "r");
        temp = fopen("G:/Studies/Project/programm/temp.dat", "w");
       
        if(!fp || !temp)
        {
                puts("  Error openning file");
                exit(1);
        }
        else
        {
      while(TRUE)
                {
                        x = fread(&tab,sizeof(tab),1,fp);
                       
                        if(!x)
                        {
            fclose(fp);
                                fclose(temp);
                                remove("G:/Studies/Project/programm/temp.dat");
                                puts("\n  Entry not match or the catalogue is empty\n\n");
                                return;
                                break;
                        }
                       
                  if(input != tab.name)
                          {fwrite(&tab,sizeof(tab),1,temp);}
                }
        }
       
        fclose(fp);
        fclose(temp);
        remove("G:/Studies/Project/programm/test.dat");
        rename("G:/Studies/Project/programm/temp.dat", "G:/Studies/Project/programm/test.dat");
        puts("  Entry deleted\n\n");
}

она мне пишет Entry not match or the catalogue is empty
и тут же выводит на экран перечень всего, что в каталоге (я что-то так и не поняла почему она не возвращается на главное меню) и то, что я просила удалить там же среди перечня.

ivank 02-02-2004 02:46 206704

Сорри, забыл про жту тему.

Цитата:

  if(input != tab.name)   {fwrite(&tab,sizeof(tab),1,temp);}
Читаем про функцию strcmp, думаем.

Цитата:

if(!x)
{
            fclose(fp);
fclose(temp);
remove("G:/Studies/Project/programm/temp.dat");
puts("\n  Entry not match or the catalogue is empty\n\n");
return;
break;
}
Здесь достаточно просто break; в скобках. Почему - думаем. (Хинт: подумай сколько раз вызывается fopen(temp); и remove("....temp.dat");)

Я бы посоветовал почитать книжку по C. Например, классику в виде Кернигана и Ритчи...

Ginger 03-02-2004 02:07 206705

ivank
кажись работает:
Код:

void delete_info(void)  //function deleting form file
{
        FILE *fp;
        FILE *temp;
        char input[30];
        char name[30];
       
        printf("  Please, enter product NAME: ");
        gets(input);
       
        fp = fopen("G:/Studies/Project/programm/test.dat", "r");
        temp = fopen("G:/Studies/Project/programm/temp.dat", "w");
       
        if(!fp || !temp)
        {
                puts("  Error openning file");
                exit(1);
        }
        else
        {
                while(fread(&tab,sizeof(tab),1,fp))
                {
                        name=tab.name;
                        if(strcmp(input, name) != 0)
                        {fwrite(&tab,sizeof(tab),1,temp);}
                }
        fclose(fp);
        fclose(temp);
        remove("G:/Studies/Project/programm/test.dat");
        rename("G:/Studies/Project/programm/temp.dat", "G:/Studies/Project/programm/test.dat");
        puts("\tEntry deleted\n");
        }
}

не надо тут никаких проверок припаять дополнительных?

млин, эта scanf() какая-то тупая - если 2 раза подряд вызывать функцию, где эта присутствует, то scanf() игнорирует предидущие инпут ф-ии (типа gets() ) и проскакивает с имени (сринг) сразу на каллорийность(интеджер).. как с ней бороться?

конечно, я взяла книжку. :) иначе как бы я сначала спрашивала ничего не зная, потом сама написала, что надо? просто сходила в библиотеку и взяла книгу: полтора дня ушло на чтение и 20 минут (с тестами) на написание того, что нужно
просто там так и было написано - удаление из файла мы здесь рассматривать не будем, потому что это долго и сложно.

ivank 03-02-2004 02:43 206706

Теперь всё вроде в порядке.

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

Ginger 03-02-2004 14:34 206707

ivank
может и мои косяки, но я сомневаюсь...
вот например функция добавления записи в файл - первый раз вызываеш её, чтобы добавить запись - всё проходит на ура. тут же хочешь добавить ешё одну запись - она проскакивает ввод имени и сразу просит ввести каллорийность.
Код:

void write_info(void) {
        FILE *veget;

          printf("Enter product name: ");
        gets(veg.name);
        printf("Enter its caloricity per 100g: ");
        scanf("%i",&veg.caloricity );
                veget = fopen("G:/Studies/Project/programm/vegetables.dat", "a");                  if(!veget)        {
                puts("Error openning file");
                exit(1);        }
        else
        {
                fwrite(&veg,sizeof(veg),1,veget);
        }
                  fclose(veget);
        puts("Entry added"); }

может есть другой способ запроса и чтения интеджер кроме  scanf?

ivank 03-02-2004 15:49 206708

Внимательно читаем документацию на ф-ии scanf и gets. В частности, scanf после считывания числа, оставляет символа перехода на новую строку во входном потоке, если его специально не попросить его убрать. А ф-ия gets, как известно считывает до первого '\n', поэтому наткнувшись на этот символ, не убранный ещё scanf'ом она сразу завершает свою работу.

Должно быть так: scanf("%d\n",&veg.caloricity );

Если, число записано на отдельной строке, то его можно считать в строку (т.е. массив char), а затем sscanf'ом или atoi перевести в число.

Ginger 03-02-2004 18:38 206709

Цитата:

Должно быть так: scanf("%d\n",&veg.caloricity );
это не работает

Цитата:

Если, число записано на отдельной строке, то его можно считать в строку (т.е. массив char), а затем sscanf'ом или atoi перевести в число.
вот этого не поняла.
предложение понятно, функции почти понятны (sscanf - не совсем понятно как работает: sscanf (input_string, "%as %as", &str_arg1, &str_arg2); - но так же можно просто scanf("%s", &string) ), но к чему это?

и спасибо за помощь и обьяснения :)

[s]Исправлено: Ginger, 18:39 3-02-2004[/s]

ivank 04-02-2004 04:14 206710

sscanf работает так же как и scanf, за тем исключением, что считывает не со стандартного потока ввода, а из строчки, которая передаётся первым параметром. К чему это было сказано: если не дружишь со scanf'ом, но дружишь с gets'ом. То считывай всё gets'ом в отдельные буферы, а затем уже из них sscanf'ом вычленяй данные как хочешь.

Т.е. вместо (псевдокод)
Код:

sscanf("%d", &calor);
gets(name);

будет что-то вроде
Код:

char buf[256+1];
// ...
gets(buf);
gets(name);
sscanf(buf, "%d", &calor);

И всё же приведи маленький рабочий пример где scanf работает неправильно. Маленький, значит не более 10 строчек, а рабочий, значит что б его можно было без всяких переделок скопипастить в свой редактор, скомпилировать и посмотреть результат. А то по куску программы трудно судить.

Ginger 04-02-2004 13:39 206711

Цитата:

И всё же приведи маленький рабочий пример где scanf работает неправильно.
18 строчек пойдут ;)
Код:

#include <stdio.h>

int main(void)
{
int x;
int i;
char y[10];
for(i=0; i<4; i++)
{
printf("Please, enter your name: ");
gets(y);
printf("Please, enter your age: ");
scanf("%i", &x);
printf("%s - %i ", y, x);
}
}

первый луп проходит на ура, но следующие нет.

Цитата:

char buf[256+1]; // ...
gets(buf);
gets(name);
sscanf(buf, "%d", &calor);
а. ясен пень :) так работает.

может тему переименовать? - Создание бд с помощью structure и file в С
к нам, конечно, никто не прикапывается, но тему мы не по названию обсуждаем. потом кому-нить пригодиться, в поиске найдёт...


[s]Исправлено: Ginger, 15:08 4-02-2004[/s]


Время: 11:28.

Время: 11:28.
© OSzone.net 2001-