Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> записать список в файл и считать из файла, нужен код на С 
:(
    Опции темы
Frekenbok
Дата 11.1.2007, 13:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 51
Регистрация: 29.10.2006

Репутация: 1
Всего: 1



Привет всем!
У меня такая проблемка возникла. Нужно записать список в файл и считать из файла. Проблема, собственно, именно с полем типа char в структуре. Компилятор древний Borland Turbo C++ 3.0.
Вот сама структура:
Код

struct node{
 char name[20];
 int price, minage, maxage;
 struct node *next;
};

Начнем с того, что не могу записать строку в поле name (ввести с клавиатуры).
Код

node *last;
 last=new (node);
printf("Введите наименование: ");
 scanf("%s", &last->name);

Так не получается. Пробовала так: cin>>last->name. Потом прочитала, что для пользовательских типов надо перегружать оператор >>. А я этого пока не умею. Хотелось бы попроще, если можно, без наворотов типа классы, пергрузка операторов и т.п. Еще пробовала cin.getline(last->name, 20). Тоже ругается. Еще был вариант такой:
Код

char str[20];
printf("Введите наименование: ");
 scanf("%s", &str);
strcpy(cur->name, str); // ругается!


Для записи в файл использую дополнительную переменную buf типа node. Элементы списка сначала записываю в buf, потом в файл.
Код

FILE *f;
f=fopen("toys.dat","wb+");
node *cur=first, buf; // first - первый элемент списка, cur - текущий элемент
 while (cur!=0){
    strcpy(buf.name,cur->name); // вот здесь ругается!!!
    buf.price=cur->price;
    buf.minage=cur->minage;
    buf.maxage=cur->maxage;
    fwrite(&buf,sizeof(buf),1,f);
    cur=cur->next;
    }

Как в поле структуры buf.name записать содержимое cur->name???

А вот считывание из файла:
Код

rewind(f);
while (!feof(f)) {
   fread(&buf, sizeof(buf), 1, f);
   last=new (node);
   strcpy(last->name,buf.name); // опять ругается!!!
   last->price=buf.price;
   last->minage=buf.minage;
   last->maxage=buf.maxage;
   last->next=NULL;
 if (first==0) first=last;
   else {
     cur=first;
     while (cur->next!=0)
       cur=cur->next;
     cur->next=last;
   }
 }


Собственно, вся проблема, наверное, в этом поле name. Оно все портит  smile  В Паскале гораздо проще было. А в С как? Помогите, пожалуйста. 
Друзья, помните, перед вами новичок!   smile 
PM MAIL   Вверх
vinter
Дата 11.1.2007, 13:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Explorer
****


Профиль
Группа: Завсегдатай
Сообщений: 2735
Регистрация: 1.4.2006
Где: Н.Новгород

Репутация: 13
Всего: 56



Код

node *last;    
 last = new node;    
printf("Введите наименование: ");    
 gets(last->name);

Цитата

Так не получается. Пробовала так: cin>>last->name. Потом прочитала, что для пользовательских типов надо перегружать оператор >>. А я этого пока не умею.

last->name не пользовательский тип данных, а обычный char массив, last вот это пользовательский тип данных, у тебя вся проблема в выделении памяти, а вообще если пишешь на С, то пиши на С, зачем его с С++ мешать??
Код

node *last;    
 last = (node *)malloc(sizeof(node));    
printf("Введите наименование: ");    
 gets(last->name);



--------------------
Мой блог
PM MAIL WWW   Вверх
PoloS
Дата 11.1.2007, 20:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 89
Регистрация: 29.12.2006
Где: МО, г. Одинцово

Репутация: 1
Всего: 5



Код

printf("Введите наименование: ");
 scanf("%s", &last->name);


так не пишется! имя массива name и есть указатель первого элемента, надо так
Код

printf("Введите наименование: ");
 scanf("%s", last->name);

PM MAIL ICQ   Вверх
kot_matros
Дата 11.1.2007, 20:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 11.1.2007

Репутация: нет
Всего: нет



Цитата

Компилятор древний

В современных делается так-же
PM MAIL   Вверх
Vsts
Дата 12.1.2007, 19:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 19
Регистрация: 10.1.2007

Репутация: нет
Всего: 1



Цитата

Компилятор древний Borland Turbo C++ 3.0.

ага, еще и не удачный... если есть возможность лучше выкинуть.
Какие ошибки компиляции там могут быть не могу предположить.Но ..
 
1)
Цитата

char str[20];
printf("Введите наименование: ");
 scanf("%s", &str);
strcpy(cur->name, str); // ругается!

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

 
   for(int pos =0;;)
    {
        while(!_kbhit()){}                
        char c = _getch();
        printf("%c",c);
        if(c == 0x0d)  // enter
       {
            str[pos] = 0;   
            break;
       }
       str[pos] = c;
       ++pos;
       if(pos >=20) break; //писать больше некуда
    }

только если используються спец символы (типа F1 , или  backspace) , то придеться доделать..
   вместо "strcpy(cur->name, str); " сделай так 
Код

 for(int i=0;i<20;++i)
{
     cur->name[i] = str[i];
     if( str[i] == 0 ) break; // конец строки
}
cur->name[19] = 0; //скорее всего тебе это пригадится!!!!!

и используй лучше вместо strcpy(..)  strncpy(..)  .избежишь кучу проблем
Цитата

FILE *f;
f=fopen("toys.dat","wb+");
node *cur=first, buf; // first - первый элемент списка, cur - текущий элемент

после f=fopen("toys.dat","wb+"); стоит проверку сделать 
if(f == NULL)  return; //или что то еще .. по контексту

када в файл пишешь, смотри что бы fwrite(&buf,sizeof(buf),1,f) == sizeof(buf)  // тоже полезно

тоже самое при чтении fread(&buf, sizeof(buf), 1, f) == sizeof(buf) ..
(это может быть чаще, например кто то дописал специально в конец файла что нить... )


Цитата

то пиши на С, зачем его с С++ мешать??
код C++
1:
2:
3:
4:
  node *last;    
 last = (node *)malloc(sizeof(node));    
printf("Введите наименование: ");    
 gets(last->name);

Цитата

Друзья, помните, перед вами новичок!    

Тогда уже так 
Код

last = (node *)malloc(sizeof(node));    
if(!last) 
{
     printf("don't memory used");
     return ;
}
printf("Введите наименование: ");    
fgets( last->name, 20, stdin );








Это сообщение отредактировал(а) Vsts - 12.1.2007, 21:00
PM MAIL   Вверх
Frekenbok
Дата 13.1.2007, 15:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 51
Регистрация: 29.10.2006

Репутация: 1
Всего: 1



Vsts, спасибо за развернутый ответ. Чувствуется рука профессионала. У меня, конечно, учебная задачка, поэтому многое не предусмотрено, но учту на будущее.
Цитата(Vsts @  12.1.2007,  19:31 Найти цитируемый пост)
for(int i=0;i<20;++i)
{
     cur->name[i] = str[i];
     if( str[i] == 0 ) break; // конец строки
}
cur->name[19] = 0; //скорее всего тебе это пригодится!!!!!

Работает  smile 
Цитата(vinter @  11.1.2007,  13:52 Найти цитируемый пост)
gets(last->name);


Цитата(PoloS @  11.1.2007,  20:03 Найти цитируемый пост)
scanf("%s", last->name);

Так тоже ошибок не выдает.
Но вот проблема, как-то в список все, видимо, коряво записывается. В общем, проблем со списками до этого не было. А тут при выводе получается ерунда. Еще раз приведу кусочки кода.
Код

...
struct node{
 char name[20];
 int price, minage, maxage;
 struct node *next;
};
node *fsttoys, buf, *last, *cur;
int i, n=2;
...
//------------добавление одного элемента списка-------------
void add (node *&first) {
 node *cur, *last, buf;
 char str[20];
 int i;
 last=new (node);
 printf("Введите name: ");
 cin>>str;

 for (i=0; i<20; ++i) { // пользуюсь дополнительной переменной и способом Vsts
   last->name[i]=str[i];
   if (str[i]==0) break;
 }

 printf"Введите price: ");
 scanf("%d", &last->price);
 printf("Введите minage: ");
 scanf("%d", &last->minage);
 printf("Введите maxage: ");
 scanf("%d", &last->maxage);

 last->next=NULL;
 if (first==0) first=last;
   else {
     cur=first;
     while (cur->next!=0)
       cur=cur->next;
     cur->next=last;
   }
 printf("\n");
}

//----------вывод списка-------------
void out (node *first) {
 node *cur=first;
 while (cur!=0)  {
  printf("%s, цена - %d коп., от %d до %d лет\n", cur->name, cur->price, cur->minage, cur->maxage);
  cur=cur->next;
 }
}

//--------основная программа------------
void main() {
 ...
 first=NULL;
 for (i=0; i<n; i++) 
   add(first);  // в цикле добавляю по одному элементу списка
 out(first);
...
}


Ввожу такие значения:
Введите name: мяч
Введите price: 100
Введите minage: 1
Введите maxage: 5

Введите name: кукла
Введите price: 240
Введите minage: 3
Введите maxage: 7


Когда вывожу список, получаю вот что:

мяч, цена - 36780 коп., от 100 до 1 лет
кукла, цена - 36780 коп., от 240 до 3 лет


В общем происходит какой-то сдвиг значения  smile 
PM MAIL   Вверх
zkv
Дата 13.1.2007, 17:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


Профиль
Группа: Участник Клуба
Сообщений: 2133
Регистрация: 23.7.2006
Где: Санкт-Петербург

Репутация: 26
Всего: 92



а как сам процесс ввода проходит? нормально? а то похоже, что мусор у тебя в прайс лезет при вводе. Код вроде нормальный, на первый взгляд, одно не нравится, используешь средства  ввода\вывода как Си так и С++ одновременно, может конечно  ничего страшного  и нет, а может и проблемы из за этого, и еще:
Цитата(Frekenbok @  13.1.2007,  15:46 Найти цитируемый пост)
 last=new (node);
 printf("Введите name: ");
 cin>>str;
 for (i=0; i<20; ++i) { // пользуюсь дополнительной переменной и способом Vsts
   last->name[i]=str[i];
   if (str[i]==0) break;
 }

зачем столько гемороя, Vsts тебе про другое говорил, а если уж ты решишь воспользоваться средствами С++, то пиши просто:
Код

last=new (node);
cin>>last->name;//тогда вместо char[20] лучше string юзать


PS заметил, что в теме ты указал язык Си, в этом случае про cin и string можно забыть...
PM MAIL   Вверх
Vsts
Дата 13.1.2007, 19:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 19
Регистрация: 10.1.2007

Репутация: нет
Всего: 1



Цитата

 Чувствуется рука профессионала. 

сотри если не тяжелоsmile...
Цитата

 У меня, конечно, учебная задачка, поэтому многое не предусмотрено...

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

вот, попробуй.Должно получиться, если скомпилиться.У меня твоего компилятора нет.
Старался как можно меньше поправок делать
Код

#include <stdio.h>


struct node
{
    char name[20];
    int price, minage, maxage;
    struct node *next;
};

node *fsttoys, buf, *last, *cur,*first;
int i, n=2;

//------------добавление одного элемента списка-------------
void add (node *&first) 
{
    node *cur, *last, buf;
    char str[20];
    int i;
    last=new (node);

    if(!last) // это может казаться песемизацией ,  но такое бывает давольна часто!!! ,лучше сразу привыкнуть ко всяким проверкам 
    {
        printf("add error :: don't memory used\n");
        return ;        
    }

    printf("Введите name: ");
    
    rewind(stdin);//очищает буфер клавиатуры

    //cin>>str;  повторюсь еще раз , юзер(препод) он считать не умеет ...  
    fgets( str, 20, stdin ); 

    printf("\n");

    // это остается , тошо вроде ты писала 
    //что с с strcpy какая то ошибка 
    //вылазит(пришлеш еррор, можно будет подумать)... 
    //но заместо strcpy пользуйся лучше strncpy !!!  
    
    //strncpy(last->name,str,20);
    for (i=0; i<20; ++i)
    { 
        if (str[i] !='\n') last->name[i]=str[i];
        else               last->name[i]=' ';

        if (str[i]==0) break;
        
    }
    last->name[19] = 0; // !!! это не просто так написано:)

    printf("Введите price: ");
    for(;;)
    {
        rewind(stdin);

        if(scanf("%d", &last->price)) break; // если правильно ввели, то scanf вернет не ноль (см МСДН)
        printf("\nError : ошибка ввода. Введите price еще раз: ");
    }
    printf("\n");

    printf("Введите minage: ");
    for(;;)
    {
        rewind(stdin);
        
        if(scanf("%d", &last->minage)) break;;
        printf("\nError : ошибка ввода. Введите minage еще раз: ");
    }
    printf("\n");


    printf("Введите maxage: ");
    for(;;)
    {
        rewind(stdin);
        
        if(scanf("%d", &last->maxage))break;
        printf("\nError : ошибка ввода. Введите maxage еще раз: ");        
    }
    printf("\n");



    last->next=NULL;
    if (first==0) first=last;
    else 
    {
        cur=first;
        while (cur->next!=0)
        cur=cur->next;

        cur->next=last;
    }
    printf("\n");
}

//----------вывод списка-------------
void out (node *first) 
{
    node *cur=first;
    while (cur!=0)  
    {
        printf("%s, цена - %d коп., от %d до %d лет\n", cur->name, cur->price, cur->minage, cur->maxage);
        cur=cur->next;
    }
}

//--------основная программа------------
void main() {
 
 first=NULL;
 for (i=0; i<n; i++) 
   add(first);  // в цикле добавляю по одному элементу списка
 out(first);
}


ПыСы када с файлами работаешь не забудь проверять(не ленись вставить) проверки всякие разные.

Это сообщение отредактировал(а) Vsts - 13.1.2007, 19:45
PM MAIL   Вверх
kot_matros
Дата 13.1.2007, 20:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 10
Регистрация: 11.1.2007

Репутация: нет
Всего: нет



Я пододобное как-раз просматривал
Вот вариант как можно забивать структуру
Код

#include <stdio.h>
#include <conio.h>


#define N ( sizeof st / sizeof st[0] )

struct D {       
    int day;
    int month; 
    int year;
    };  

struct {
    char name_of_factory[30]; //наименование предприятия
    int state;                //состояние заказа(выполнен, не выполнен)
    float price;              //стоимость заказа

    struct D date;            //дата поступления заказа
    } st[]= {
            "ATC",                0,    2000.0,    { 2, 5, 1999 },
            "Haulier",                1,    670.0,    { 8, 11, 2000 },
            "Housing and Communal Services",    1,    1200.0,    { 30, 12, 2004 },
            "Electric Power Station",        0,    2100.0,    { 25, 11, 2006 },
            "Restaurant",            1,    2000.0,    { 1, 1, 2007 },
            "Agricultural Production",        0,    200.0,    { 28, 2, 1998 },
            "School",                1,    500.0,    { 4, 4, 2006 },
            "Public Lavatory",            1,    20.0,    { 1, 1, 2007 }
            };

 
void main(void)
{
int c;

textcolor( WHITE );
textbackground( CYAN );

clrscr();
window( 4, 4, 80, 25 );

for( c=0; c <N; c++ )
{
    cprintf( "\n-------- Order numer %d ---------\n\r", c+1 );
    cprintf( "Name of factory  \" %s \"\n\r", st[c].name_of_factory );
    cprintf( "State  %d \n\r", st[c].state );
    cprintf( "Valiue $%10.2f\n\r", st[c].price );

    cprintf( "Date: %d.%d.%d\n\r", st[c].date.day, st[c].date.month,
    st[c].date.year );

    cprintf( "Press any key ...\n\r" );
    getch();
    }

return;
}

А вот как забить из фаулта
Код

#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <stdlib.h>


struct D {       
    int day;
    int month; 
    int year;
    };  

struct Order {
    char name_of_factory[30]; //наименование предприятия
    int state;                //состояние заказа(выполнен, не выполнен)
    float price;              //стоимость заказа

    struct D date;            //дата поступления заказа
    };


void main()
{
int i, q, j, c, ch, N;
char *buf=NULL;
struct Order *st;


FILE *f;
if( (f=(fopen( "Sdata.txt", "r" ))) !=NULL );
else
{
    perror( "Error reading \n");
    exit(1);
    }

fseek( f, 0L, SEEK_SET );
for( N=0; ; i++ )
{
    ch =fgetc( f );
    if( ch ==EOF || ch =='\0' )
    {
        N++;
        break;
        }
    else if( ch =='\n' && i==0 ) N++;
    else if( ch =='\n' ) i=-1;
    }


if( N ==0 )
{
    printf( "File Length of zero: %s", "Sdata.txt" );
    exit(1);
    }
else if( (st=( Order * ) malloc( (N+1)*sizeof(Order)) ) == NULL )

    perror( "Not enough memory to allocate buffer\n" );
    exit(1); 
    }
else if( (buf = (char *) malloc( 80*sizeof(char))) == NULL )
{
    printf("Not enough memory to allocate buffer\n");
    exit(1); 
    }


fseek( f, 0L, SEEK_SET );

for( i=0, j=0; !feof( f ); j++ )
{
    fgets( buf, 80, f );
    if( buf[0] =='\n' )
    {
        i++;
        j=-1;
        continue;
        }
    else if( buf[strlen(buf)-1] =='\n' ) buf[strlen(buf)-1] ='\0';

    if( j==0 )        strcpy( st[i].name_of_factory, buf );
    else if( j==1 )    st[i].state =atoi( buf );
    else if( j==2 )    st[i].price =atoi( buf );
    else if( j==3 )    st[i].date.day =atoi( buf );
    else if( j==4 )    st[i].date.month =atoi( buf );
    else if( j==5 )    st[i].date.year =atoi( buf );
    }

textcolor( WHITE );
textbackground( CYAN );

clrscr();
window( 4, 4, 80, 25 );

for( c=0; c <N; c++ )
{
    cprintf( "\n-------- Order numer %d ---------\n\r", c+1 );
    cprintf( "Name of factory  \" %s \"\n\r", st[c].name_of_factory );
    cprintf( "State  %d \n\r", st[c].state );
    cprintf( "Valiue $%10.2f\n\r", st[c].price );

    cprintf( "Date: %d.%d.%d\n\r", st[c].date.day, st[c].date.month,
    st[c].date.year );

    cprintf( "Press any key ...\n\r" );
    getch();
    }

fclose( f ); 
free( st );
free( buf );

return;
}

т.к ф коде нет проверок на ошибки файл должен быть точно
такого вида:
Код

ATC
0
2000.0
2
5
1999

Haulier
1
670.0
8
11
2000

Housing and Communal Services
1
1200.0
30
12
2004

Electric Power Station
0
2100.0
25
11
2006

Restaurant
1
2000.0
1
1
2007

Agricultural Production
0
200.0
28
2
1998

School
1
500.0
4
4
2006

Public Lavatory
1
20.0
1
1
2007

PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0928 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.