Ветеран
Сообщения: 3320
Благодарности: 916
|
Профиль
|
Отправить PM
| Цитировать
pva, возможно покажусь назойливым, но всё же, возможно ли структуру в читабельном виде сохранить в файл, что б при чтении обратно программа понимала что это структура? В примерах про структуры показывается что нет - только бинарное представление.
В каких случаях стоит использовать union(объединение)? Это ведь таже структура, только более щадящая память за счёт размещения всех полей по одному и тому же адресу.
Вместо пробелов всё же хочется задействовать табуляцию. В качестве примера я взял предыдущий - про телефонную станцию.
Вот её структура
Код: 
struct PhoneStatistic
{
char date[8+1]; //1. дата (8 симв, ддммгггг)
char time[6+1]; //2. время (6 символов ччммсс)
char dialing[11+1]; //3. исходящий номер (11 симв)
char incoming[11+1]; //4. входящий номер (11 симв)
char duration[4+1]; //5. время разговора (4 симв)
char price[10+1]; //6. стоимость разговора (10 симв)
char *notes; //7. новое поле переменно не определённой/не известной длины для эксперимента
};
ещё один прибавляем для NULL символа
Визуально всё хорошо получается (используя printf), да вот возникает сложность сбора данных в поля структуры.
Используя printf можно в цикле выводить символы, при этом на экране складывается слово. По идеи, тоже самое можно сделать для полей структуры через sprintf. Да вот не задачка, не проходит.
stdout это стандартный поток вывод, а stdin - ввода. Возможно, ли каким-то образом используя их комбинацию заполнять поля структуры данными выводимыми printf'ом? То есть что б они брались с экрана?
Возможно ли во время выполнения программы узнать количество полей/элементов структуры? Так как в программе приходится за каждым элементом закреплять свой цикл.
Код, построенный на примере про fread по ссылке выше
Код: 
/* fread example: read a complete file */
#include <stdio.h>
#include <stdlib.h>
//#include <string.h>
#define CR 0x0d //Возврат каретки
#define SP 0x20 //Пробел
struct PhoneStatistic
{
char date[8+1]; //1. дата (8 симв, ддммгггг)
char time[6+1]; //2. время (6 символов ччммсс)
char dialing[11+1]; //3. исходящий номер (11 симв)
char incoming[11+1];//4. входящий номер (11 симв)
char duration[4+1]; //5. время разговора (4 симв)
char price[10+1]; //6. стоимость разговора (10 симв)
char *notes; //7. новое поле переменно не определённой/не известной длины для эксперимента
};
int main(int argc, char* argv[])
{
if (argc<=1)
{
printf("\nUsage: %s <File Name>",argv[0]);
return 0;
}
FILE * pFile;
long lSize;
char * buffer;
size_t result;
pFile = fopen ( argv[1] , "rb" );
if (pFile==NULL) {fputs ("File error",stderr); exit (1);}
// obtain file size:
fseek (pFile , 0 , SEEK_END);
lSize = ftell (pFile);
rewind (pFile);
// allocate memory to contain the whole file:
buffer = (char*) malloc (sizeof(char)*lSize);
if (buffer == NULL) {fputs ("Memory error",stderr); exit (2);}
// copy the file into the buffer:
result = fread (buffer,1,lSize,pFile);
if (result != lSize) {fputs ("Reading error",stderr); exit (3);}
/* the whole file is now loaded in the memory buffer. */
fclose (pFile);
unsigned int i;
unsigned int Tabs=0;
unsigned int Enters=0;
unsigned int Newlines=0;
unsigned int Spaces=0;
for (i=0;i<result;i++)
{
//printf("%c",buffer[i]);
/*Если раскомментировать строчку выше,
то всё что после данного цикла до free (buffer);
можно убрать и визуально вывод не пострадает.*/
switch (buffer[i])
{
case '\t': Tabs++; break;
case '\n': Enters++; break;
case CR: Newlines++; break;
case SP: Spaces++; break;
default: break;
}
}
printf("\t\tStatistics\n Pages *\n Words *\n Characters \t\t\t%i\n Characters (with spaces) \t%i\n Tabs \t\t\t\t%i\n Entered \t\t\t%i\n Lines \t\t\t\t%i\n Spaces \t\t\t%i\n",i-Spaces,i-Enters,Tabs,Enters,Newlines,Spaces);
PhoneStatistic *currentStatistic = new PhoneStatistic[Newlines];
/*Возможно покажется что данные булевые переменные,
но они рассчитаны, по крайне мере запланированы,
на тот случай если структура файла будет нарушена*/
bool lockDate = false;
bool lockTime = true;
bool lockDialing = true;
bool lockIncoming = true;
bool lockDuration = true;
bool lockPrice = true;
bool lockNotes = true;
//unsigned int j;
for(i=0;i<result;i++)
{
while ((buffer[i]!='\t') && (!lockDate))
{
if (buffer[i]=='\n') break;
printf("%c",buffer[i]);
i++;
}
lockDate = true;
printf("%c",buffer[i]);//здесь и дальше вне циклов while будет вывод для визуальной разметки, табуляции и символы новой строки
i++;
lockTime = false;
while ((buffer[i]!='\t') && (!lockTime))
{
if (buffer[i]=='\n') break;
printf("%c",buffer[i]);
//sprintf(currentStatistic[j].time,"%c",buffer[i]);
//printf("%c",currentStatistic[j].time);
i++;
}
lockTime = true;
printf("%c",buffer[i]);
i++;
lockDialing = false;
while ((buffer[i]!='\t') && (!lockDialing))
{
if (buffer[i]=='\n') break;
printf("%c",buffer[i]);
//sprintf(currentStatistic[j].dialing,"%c",buffer[i]);
//printf("%c",currentStatistic[j].dialing);
i++;
}
lockDialing = true;
printf("%c",buffer[i]);
i++;
lockIncoming = false;
while ((buffer[i]!='\t') && (!lockIncoming))
{ if (buffer[i]=='\n') break;
printf("%c",buffer[i]);
//sprintf(currentStatistic[j].incoming,"%c",buffer[i]);
//printf("%c",currentStatistic[j].incoming);
i++;
}
lockIncoming = true;
printf("%c",buffer[i]);
i++;
lockDuration = false;
while ((buffer[i]!='\t') && (!lockDuration))
{ if (buffer[i]=='\n') break;
printf("%c",buffer[i]);
//sprintf(currentStatistic[j].duration,"%c",buffer[i]);
//printf("%c",currentStatistic[j].duration);
i++;
}
lockDuration = true;
printf("%c",buffer[i]);
i++;
lockPrice = false;
while ((buffer[i]!='\t') && (!lockPrice))
{ if (buffer[i]=='\n') break;
printf("%c",buffer[i]);
//sprintf(currentStatistic[j].price,"%c",buffer[i]);
//printf("%c",currentStatistic[j].price);
i++;
}
lockPrice = true;
printf("%c",buffer[i]);
i++;
lockNotes = false;
while ((buffer[i]!='\n') && (!lockNotes))
{
if (i==result) break;
printf("%c",buffer[i]);
//sprintf(currentStatistic[j].notes,"%c",buffer[i]);
//printf("%c",currentStatistic[j].notes);
i++;
}
//if (buffer[i]=='\n') j++;
if (i==result) break;
lockNotes = true;
printf("%c",buffer[i]);
//i++; Дадим циклу for увеличить счётчик :)
lockDate = false;
}
free (buffer);
//currentStatistic if ((buffer[i]!=CR)/*0x0d*/
//printf("\n");
//for (int j=0;j<Newlines;j++)
// printf("%s",currentStatistic[j].date);
return 0;
}
Пример статистики
22042009 225914 89163421111 89076958093 120 4500 importante
22042009 230454 89163421111 89076958093 120 4500 secure
Отличие, от данных которые привёл pva выше - в добавленной табуляции между полями + новое поле.
|