Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Для новичков > Проблема со считыванием разнотипных данных из фай


Автор: Hotrod 11.1.2010, 10:24
Всем доброго времени суток!
Дело вот в чем.
В файле содержатся данные в формате: 
<Автор(char)> "<Название картины(char)>" <цена(double)> <возраст картины(int)>

помогите, пожалуйста, забить это в структуру(список)(В Си, не в C++):
Код


Struct K;
{char name[80];
 char title[80];
 double r;
 double age;
/*ну ясно, для списка двусвязного еще указатели:*/
struct K *prev;
struct K *next;} 


Заранее премного благодарен!

Автор: bsa 11.1.2010, 12:00
читаешь файл построчно, затем находишь в считанной строке первое включение символа двойных кавычек, все что до него - автор, затем находишь второе включение кавычек - все что между первыми и вторыми это название, оставшуюся часть строки парсишь с помощью sscanf(str+pos+1, "%lf %lf", &picture->r, &picture->age), где str - строка считанная из файла, pos - позиция последней кавычки, picture - указатель на переменную типа struct K.
Кстати, struct K - довольно странное название. Может стоит переименовать в PicInfo или во что-то, что сможет в дальнейшем понять, что же этот тип значит?

Автор: and277 11.1.2010, 14:58
bsa , а в с++ попроще разбор мне кажется.... smile 

Автор: bsa 11.1.2010, 15:09
and277
Цитата(Hotrod @  11.1.2010,  10:24 Найти цитируемый пост)
(В Си, не в C++)

Автор: and277 11.1.2010, 15:15
bsa , уже прочел шапку...

А поправьте меня если я ошибаюсь:    в файл нет смысла записывать объекты, в которых есть указатели? 


Автор: bsa 11.1.2010, 15:31
Нет смысла записывать указатели. Строка в стиле Си (которая char*) тоже хранится скорее всего в виде указателя. Но почему-то ни у кого не возникает вопросов про необходимость ее сохранения. Так же и про остальные указатели - записывать нужно не значение указателя, а объект на который он ссылается, или еще как-нибудь его обозначать (индекс и т.п.).

Автор: and277 11.1.2010, 15:45
Цитата(bsa @ 11.1.2010,  15:31)
Нет смысла записывать указатели. Строка в стиле Си (которая char*) тоже хранится скорее всего в виде указателя. Но почему-то ни у кого не возникает вопросов про необходимость ее сохранения. Так же и про остальные указатели - записывать нужно не значение указателя, а объект на который он ссылается, или еще как-нибудь его обозначать (индекс и т.п.).

Спасибо... Доходчиво объяснил

Автор: Hotrod 12.1.2010, 00:13
Код

if(!feof(f))
    { fgets(str,255,f); int q=250;
    for(i=0;i<q,str[i]!='\0';i++) q=i;
    //printf("%s",str);
    for(i=0;(str[i+1]!='"');i++) { name[i]=str[i]; n=i+1;}; 
    for((i=n+2),j=0;(str[i]!='"');i++,j++) {title[j]=str[i]; m=i;}; 
    for((i=m+4),j=0;str[i]!='"';i++,j++) {rs[j]=str[i]; p=i;};  //r  в строковом формате
    for((i=p+3),j=0;i<q;i++,j++) {ages[j]=str[i];};  //age в строковом формате
    };

 теперь остается atof(rs) и atoi(ages). А вот как это в структуру забить через указатели? Да, и еще: компилятор к name  и title добавляет какие-то странные символы, как их убрать?

Автор: Hotrod 12.1.2010, 02:42


Код

if(!feof(f))
        { fgets(str,250,f); int q=250;
        for(i=0;i<q,str[i]!='\0';i++) q=i;
        //printf("%s",str);
        for(i=0;(str[i+1]!='"');i++) { name[i]=str[i]; n=i+1;}; name[n]='\0';
        for((i=n+2),j=0;(str[i]!='"');i++,j++) {title[j]=str[i]; title[i+1]='\0'; m=i;}; 
        for((i=m+4),j=0;str[i]!='"';i++,j++) {rs[j]=str[i]; p=i;};  
        for((i=p+3),j=0;i<q;i++,j++) {ages[j]=str[i];};  
        r=atof(rs); age=atoi(ages);
        };



Все, теперь помогите мне это в список загнатьsmile

Автор: bsa 12.1.2010, 11:17
Hotrod, а тебе нельзя пользоваться такими стандартными функциями, как strlen, strcpy, strcspn и sscanf?
Код
int age;
double cost;
char title[100];
char author[100];
...
fgets(str,250,f);
size_t authorSize = strcspn(str, "\"");
if ( (authorSize == 0) || (authorSize > sizeof(author) - 1) )
   return -1;  //author name is empty or more than 99

strncpy(author, str, authorSize); //копируем не более q1pos первых символов в author
author[authorSize] = '\0';

const char *titleBegin = str + authorSize + 1;
size_t titleSize = strcspn(titleBegin, "\"");

if ( (titleSize == 0) || (authorSize > sizeof(author) - 1) )
   return -1;  //title is empty or more than 99

strncpy(title, titleBegin, titleSize);
title[titleSize] = '\0';

if (sscanf(titleBegin + titleSize + 1, "%lf %i", &cost, &age) != 2)
   return -1; //invalid cost or age format

...

Автор: xvr 12.1.2010, 12:48
Через strtok будет еще проще:
Код

fgets(str,255,f);
char* name = strtok(str,"\"");
char* title = strtok(NULL,"\"");
char* price = strtok(NULL," ");
char* age = strtok(NULL," \n");

K* k = ...
strncpy(k->name,name,sizeof(k->name));
strncpy(k->title,title,sizeof(k->title));
k->price = atof(price);
k->age = atoi(age);

Автор: bsa 12.1.2010, 13:00
xvr, у тебя ошибка:
Цитата(man strncpy)
Warning: If there is no null byte among the first n bytes of src, the string placed in dest will not be null terminated.

Автор: xvr 12.1.2010, 20:15
Цитата(bsa @ 12.1.2010,  13:00)
xvr, у тебя ошибка:
Цитата(man strncpy)
Warning: If there is no null byte among the first n bytes of src, the string placed in dest will not be null terminated.

Я в курсе. В твоем посте (2 штуки назад) довольно подробно расписанно как использовать strncpy. 
Я написал только самую суть, что бы не загромождать текст. Надеюсь, что ТС сможет дописать остальное  smile 


Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)