Тема: Робота з файлами в С

Сформувати файл “В”, записами якого є: прізвища письменників, ініціали, назви книги, рік видання. Використовуючи ці данні, сформувати файл “Е”, де розмістити прізвища письменників, які видають більше двох книг за рік.
Я побачив що тему видалили ,через те що не було напрацювань.

#include<stdio.h>
#include<stdlib.h>
struct Library
{
    char SurName[25];
    char Name[25];
    char BookName[36];
    int Year;
};
int main()
{
    FILE *file;
    int i,j;
    struct Library str[3];
    struct tmp;
    for(i=0;i<3;i++)
    {
        printf("Введіть прізвище ");
        scanf("%s",str[i].SurName);
        printf("Введіть ініціали ");
        scanf("%s",str[i].Name);
        printf("Введіть назву книжки ");
        scanf("%s",str[i].BookName);
        printf("Введіть рік видання ");
        scanf("%d",& str[i].Year);
    }
    file=fopen("library","w");
    if(file==NULL)
    {
        printf("Помилка при відкриванні файлу");
        exit(0);
    }
    for(i=0;i<3;i++)
    {
        fprintf(file,"%d %s %s %s %d\n",i+1,str[i].SurName,str[i].Name,str[i].BookName,str[i].Year);
    }
    fclose(file);
}

Я трішки розібрався з файлами і зрозумів суть завдання.
Зробив через структуру , для прикладу зробив з 3, і вніс структуру в файл , а дальше не можу виділити прізвища письменників , які видають більше 2 книжок за рік ( думаю, що потрібно робити через розгалуження , але не можу реалізувати). Поможіть будь ласка.

2 Востаннє редагувалося koala (04.12.2019 00:34:10)

Re: Робота з файлами в С

Для початку, з файлами можна працювати як з текстовими чи двійковими. Халепа текстових у тому, що fscanf читає "%s" до пробіла, тобто ім'я чи назва книжки з пробілом Surname="Tolkien",Name ="John R.R.",BookName="The Lord of the Rings" будуть ламати вам програму. Це можна вирішити, якщо замість fscanf використовувати getlinegets і читати/писати по рядках; але можна просто писати у файл як у двійковий:

fwrite(&str, sizeof struct Library, 3, file); //записати весь масив
fread(&str[i], sizeof struct Library, 1, file); //прочитати одну структуру в str[i]

Тоді в файл може записуватися сміття з фрагментів після закінчення рядків, зате запис-читання стають дуже простими. Звісно, це можна робити лише зі структурами, що містять всі дані в собі, а не посилання на них. char * так зберегти не вдасться.

Далі. Для роботи з файлами існує 2 стратегії:
1. Читати/писати у файл по одному елементу. Це класичний метод; його перевага в тому, що пам'яті витрачається зовсім мало.
2. Читати/писати одразу весь файл. Це популярно в наші часи, коли мегабайт пам'яті коштує менше цента; перевага в простоті програми.
Вам слід обрати якусь із цих стратегій і її дотримуватися; але зазвичай файли вивчають саме для того, щоб ознайомитися з першою стратегією - зрештою, прочитати 20ГБ файл може ще далеко не кожен комп'ютер, а от обробити його маленькими шматочками зможе і досить старе залізо.

Ну і нарешті ваше питання. Спробуйте уявити собі, що у вас є купа різнокольорових кубиків, і вам треба знайти ті, кольори яких повторюються. Як ви це робитимете? Зможете описати алгоритм словами?

Прихований текст
Oleg Kulynych написав:

думаю, що потрібно робити через розгалуження

Судячи з вашого припущення, вам ще дуже рано вивчати файли. Це припущення на рівні "щоб написати вірш, треба скористатися приголосними літерами". Ну, так, звісно, треба, важко заперечити; але для того, щоб написати вірш, треба володіти кількома значно складнішими абстракціями.

3

Re: Робота з файлами в С

Я знайшов рішення цієї задачі , ось. Але ця проблема із пробілами , можна трішки докладніше.

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct Library
{
    char SurName[25];
    char Name[25];
    char BookName[36];
    int Year;
};
int main()
{
    FILE *file;
    FILE *file1;
    int i,j;

    struct Library str[6];
    struct Library tmp[6];
    for(i=0;i<6;i++)
    {
        printf("Введіть прізвище ");
        scanf("%s",str[i].SurName);
        printf("Введіть ініціали ");
        scanf("%s",str[i].Name);
        printf("Введіть назву книжки ");
        scanf("%s",str[i].BookName);
        printf("Введіть рік видання ");
        scanf("%d",& str[i].Year);
    }
    file=fopen("B","w");
    if(file==NULL)
    {
        printf("Помилка при відкриванні файлу");
        exit(0);
    }
    for(i=0;i<6;i++)
    {
        fprintf(file,"%d %s %s %s %d\n",i+1,str[i].SurName,str[i].Name,str[i].BookName,str[i].Year);
    }
    fclose(file);
    int n=0;
    file1=fopen("E","w");
    if(file1==NULL)
    {
        printf("Помилка при відкриванні файлу");
        exit(0);
    }
    for(i=0;i<5;i++)
    {
        for(j=i+1;j<6;j++)
        {
            if(strcmp(str[i].SurName,str[j].SurName)==0)
            {
                if(str[i].Year==str[j].Year)
                {
                            fprintf(file1,"%s\n",str[i].SurName);
                }
            }
        }
    }
    fclose(file1);
}

4

Re: Робота з файлами в С

(глибоко позіхає)
ну добре, якщо вас це влаштовує, то хай так і буде. Я не ваш викладач.
Щодо пробілів - могли б уже нагуглити стандартну бібліотеку. Так, не getline, gets/fgets.

Подякували: Oleg Kulynych1

5

Re: Робота з файлами в С

struct Library
типова помилка. знайти б першого, хто це винайшов та одпиляти руки

6 Востаннє редагувалося ur_naz (04.12.2019 02:20:23)

Re: Робота з файлами в С

del

7

Re: Робота з файлами в С

Може, зменшите вже рівень радикалізму? Бо так вам же першому руки і відпиляють.

8

Re: Робота з файлами в С

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct Library
{
    char SurName[100];
    char Name[100];
    char BookName[100];
    int Year;
};
int main()
{
    FILE *file;
    FILE *file1;
    int i,j,n;
    printf("Введіть кількість записів");
    scanf("%d%*c",&n);
    struct Library str[n];
    struct Library tmp[n];
    for(i=0;i<6;i++)
    {
        printf("Введіть прізвище ");
        fgets(str[i].SurName,sizeof(str[i].SurName),stdin);
        printf("Введіть ініціали ");
        fgets(str[i].Name,sizeof(str[i].Name),stdin);
        printf("Введіть назву книжки ");
        fgets(str[i].BookName,sizeof(str[i].BookName),stdin);
        printf("Введіть рік видання ");
        scanf("%d%*c",&str[i].Year);
    }
    file=fopen("B","w");
    if(file==NULL)
    {
        printf("Помилка при відкриванні файлу");
        exit(0);
    }
    for(i=0;i<6;i++)
    {
        fprintf(file,"%d %s %s %s %d\n",i+1,str[i].SurName,str[i].Name,str[i].BookName,str[i].Year);
    }
    fclose(file);
    file1=fopen("E","w");
    if(file1==NULL)
    {
        printf("Помилка при відкриванні файлу");
        exit(0);
    }
    for(i=0;i<5;i++)
    {
        for(j=i+1;j<6;j++)
        {
            if(strcmp(str[i].SurName,str[j].SurName)==0)
            {
                if(str[i].Year==str[j].Year)
                {
                            fprintf(file1,"%s\n",str[i].SurName);
                }
            }
        }
    }
    fclose(file1);
}

Ось я вирішив проблему з пробілами

9

Re: Робота з файлами в С

koala написав:

Може, зменшите вже рівень радикалізму? Бо так вам же першому руки і відпиляють.

Дати пилку? ви гляньте, що воно коїться. хто ж пише в файл поки вводить з консолі?

10

Re: Робота з файлами в С

ur_naz написав:
koala написав:

Може, зменшите вже рівень радикалізму? Бо так вам же першому руки і відпиляють.

Дати пилку? ви гляньте, що воно коїться. хто ж пише в файл поки вводить з консолі?

То, може, коротеньку статтю напишете про це?

Подякували: ping1

11

Re: Робота з файлами в С

нащо? хто ті статті читає?

12

Re: Робота з файлами в С

ur_naz написав:

нащо? хто ті статті читає?

А нащо ви взагалі на цей форум прийшли?

Подякували: leofun011

13

Re: Робота з файлами в С

нащо взагалі жити? нащо ці запитання? я звертаюся до тс. якщо йому стане розуму, буде розмова, якщо ні, то ні

14

Re: Робота з файлами в С

ur_naz написав:

нащо? хто ті статті читає?

Наприклад я читаю

Подякували: koala1

15

Re: Робота з файлами в С

вчитись треба по підручниках. і не по інститутських шпаргалках, а по англомовних виданнях

16

Re: Робота з файлами в С

Тоді поясніть, будь ласка, мені - і чому ж це не можна одночасно читати з файлового потоку і писати в консольний? Ідея потоків якраз і була в тому, щоб можна було не думати, з якими конкретно потоками ви зараз працюєте, решту має вирішувати буферизація.

Подякували: leofun011