Файлы, чтение и запись структур в C

Можно спросить у ТС, насколько ему критично использование СИ?

Я пока являюсь новичком, поэтому в языке с++ не очень разбираюсь( но хочу перейти после изучения си на него

Тогда примеры на выбор:
#cpp Пост 8
#c Чтение и запись структур в файл

Возникнут вопросы обращайтесь.

как раз над этим сижу)))

ребят, помогите, пожалуйста, с загрузкой!(((

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
struct zv_koordinati 
{
double ugol;
int chas, min;  /* координаты на небосклоне (15° 23 ч 27 мин) */
};
 
struct rasdozamli 
{
double ras; 
int godkm;  /* расстояние до Земли ( в св. годах или в км) */
};
 
struct zvezda 
{
char zv_name[20];           /* название (Солнце) */
double zv_velichina;        /* видимая величина (-26,74) */
struct zv_koordinati k; 
struct rasdozamli l;
};
 
void vivodinfo(const struct zvezda *p)
{
    printf("Название звезды: \t %s \n", p -> zv_name);
    printf("Видимая величина: \t %lg \n", p -> zv_velichina);
    printf("Расстояние до Земли: \t %lg %s \n", p -> l.ras, (p -> l.godkm ? "св.лет" : "км"));
    printf("Координаты на небосклоне: \t %lg°   %d ч %d мин \n\n", p -> k.ugol, p -> k.chas, p -> k.min);        
}
 
void vvodzvkoordinati(const struct zv_koordinati *p)
{   
    fflush(stdin);
    printf("\nУгол:\t");
    scanf("%lg", &p->ugol);
    while (p->ugol < -90 || p->ugol > 90) {
    printf("\nОшибка. Введите угол ещё раз (от -90 до 90)!\n");
    printf("\nУгол:\t");
    fflush(stdin);
    scanf("%lg", &p->ugol); 
    }
 
    fflush(stdin);
    printf("Часы:\t");
    scanf("%d", &p->chas);
    while (p->chas < 0 || p->chas > 23) {
    printf("\nОшибка. Введите часы ещё раз (формат - 24 часа)!\n");
    printf("Часы:\t");
    fflush(stdin);
    scanf("%d", &p->chas);  
    }
 
    fflush(stdin);
    printf("Минуты:\t");
    scanf("%d", &p->min);
    while (p->min < 0 || p->min > 59) {
    printf("\nОшибка. Введите минуты ещё раз (в часе 60 минут)!\n");
    printf("Минуты:\t");
    fflush(stdin);
    scanf("%d", &p->min);   
    }
}
 
void vvod(struct zvezda *p) 
{
    fflush(stdin);
    printf("Название звезды:\t");
    scanf("%s", &p -> zv_name);
    fflush(stdin);
    printf("Видимая величина:\t");
    scanf("%lg", &p -> zv_velichina);
    fflush(stdin);
    printf("Расстояние до Земли:\t");
    scanf("%lg", &p -> l.ras);
    fflush(stdin);
    printf("\nРасстояние до Земли записано в световых годах или километрах?\n");
    printf("Если в св. годах, то нажмите - 1, если в километрах нажмите - 0: ");
    scanf("%d", &p -> l.godkm);
    while (p->l.godkm > 1 || p->l.godkm < 0) {
    printf("\nОшибка. Повторите попытку!\n");
    printf("Введите 1 (св года) или 0 (км): ");
    fflush(stdin);
    scanf("%d", &p->l.godkm); }
    fflush(stdin);
    printf("\nКоординаты на небосклоне:\t");
    vvodzvkoordinati(&p -> k);
}
 
void poisk(const struct zvezda A[], int n, double zv1)
{
    int i, k;
    for (i = 0, k = 0; i < n; i++)
    if (A[i].zv_velichina == zv1)
    {
      printf("\n*** Запись № %d ***\n", ++k);
      vivodinfo(&A[i]);
    }
    printf("\nНайдено %d записей из %d.\n", k, n);  
}
 
int dobav_number(int n) 
{
    int k;
    if (n == 0){return 0;}
    
    if (n == 1){return 1;}
    
    fflush(stdin);
    printf("Укажите номер записи для вставки новой записи (от 1 до %d): ", n);
    scanf("%d", &k); 
    while (k < 1 || k > n) {
    printf("Ошибка. Проверьте правильность ввода и повторите попытку!\n");
    printf("Укажите номер записи для вставки (от 1 до %d): ", n);
    fflush(stdin);
    scanf("%d", &k);       }
    
    return k;   
}
 
int udal_number(int n) 
{
    int k;
    
    if (n == 0){return 0;}
    
    if (n == 1){printf("Запись №1 удалена!\n\n");return 1;}
    
    fflush(stdin);
    printf("Укажите номер записи, которую необходимо удалить (от 1 до %d): ", n);
    scanf("%d", &k); 
    while (k < 1 || k > n) {
    printf("Ошибка. Проверьте правильность ввода и повторите попытку!\n");
    printf("Укажите номер записи, которую необходимо удалить (от 1 до %d): ", n);
    fflush(stdin);
    scanf("%d", &k);       }
    
    printf("Запись №%d удалена!\n\n", k);
    
    return k;   
}
 
int vivod_number(int n)
{
    int k;
    if (n == 0){return 0;}
    
    if (n == 1){return 1;}
    
    fflush(stdin);
    printf("Укажите номер записи для её поиска (от 1 до %d): ", n);
    scanf("%d", &k); 
    while (k < 1 || k > n) {
    printf("Ошибка. Проверьте правильность ввода и повторите попытку!\n");
    printf("Укажите номер записи для её поиска (от 1 до %d): ", n);
    fflush(stdin);
    scanf("%d", &k);       }
    
    return k;
}
 
int sravnenie(const struct zvezda *p1, const struct zvezda *p2)
{
    double rast1, rast2;
    
    if (p1 -> l.godkm)
    rast1 = p1->l.ras*9460730472580820.0;
    else
    rast1 = p1->l.ras;
    
    if (p2 -> l.godkm)
    rast2 = p2->l.ras*9460730472580820.0;
    else
    rast2 = p2->l.ras;
    
    return rast1 > rast2 || rast1 == rast2;     
}
 
void sort(struct zvezda A[], int n)
{
  int i, j;
  for (j = 1; j < n; j++)
    for (i = 0; i < n-j; i++)
      if (sravnenie(&A[i], &A[i+1]))
      {
        struct zvezda temp;
        temp = A[i];
        A[i] = A[i+1];
        A[i+1] = temp;
      }
}
 
int save (struct zvezda *p, int n)
{
    FILE *file;
    char fname[20];
    char *c;
    int size = n * sizeof(struct zvezda); // количество записываемых байтов
    int i;
 
    printf("Введите имя файла, в который будут сохранены существующие записи: ");
    scanf ("%s", fname);
    file=fopen(fname, "a");
    if (file == NULL)
    {
        printf("Возникла ошибка!");
        return(0);
    }
    
    //записываем количество структур
    c = (char *)&n;
    for (i = 0; i < sizeof(int); i++)
    {
        putc(*c++, file);
    }
    
    //посимвольно записываем в файл все структуры
    c = (char *)p; 
    
    for (i = 0; i < size; i++) 
    {
        putc(*c, file); 
        c++;
    }
    
    fclose(file);
    return 0;
}
 
int zagruzka (struct zvezda *p)
{
    FILE *file;
    char fname[20];
    char *c;
    int m = sizeof(int);
    int i, n; 
    
    //выделяем память для количества данных
    int *pti = (int *)malloc(m); 
    
    printf("Введите имя файла, из которого будут загружены записи: ");
    scanf ("%s", fname);
    file=fopen(fname, "r");
    if (file == NULL)
    {
        printf("Возникла ошибка!");
        return(0);
    }
    
    //считываем количество структур
    c = (char *)pti; 
    while (m > 0)
    {
        i = getc(file);
        if (i == EOF) break;
        *c = i;
        c++;
        m--;
    }   
    //получаем число элементов
    n = *pti; 
    
    struct zvezda *ptr = (struct zvezda *) malloc(n * sizeof(struct zvezda));
    c = (char *)ptr;
    
    while ((i= getc(file)) != EOF)
    {
        *c = i;
        c++;
    }
 
    free(pti);
    free(ptr);
    fclose(file);
    return 0;
}
 
int main()
{
    struct zvezda A[50];
    int number, n=0, i, k, d=0;
    double zv;
 
    system("chcp 1251 > nul");
    
    while (d<2) {
        
    system("cls");
    
     printf("___________________________________________________________________\n"
            "********************|-----------MENU----------|********************\n"
            "*******************************************************************\n"
            "*   1. Добавить запись                                            *\n"
            "*   2. Вставить запись                                            *\n"
            "*   3. Удалить запись                                             *\n"
            "*   4. Просмотреть запись                                         *\n"
            "*        41 - по указанному номеру                                *\n"
            "*        42 - по видимой величине                                 *\n"
            "*        43 - все записи                                          *\n"
            "*   5. Сортировать записи (по возрастанию расстояния до Земли)    *\n"
            "*   6. Сохранить записи в файл                                    *\n"
            "*   7. Загрузить записи из файла                                  *\n"
            "*   ???                                                           *\n"
            "*   9. Выйти из меню                                              *\n"
            "*******************************************************************\n>> ");
 
    fflush(stdin);
    scanf("%d", &number);
    
    switch (number) {
        
    case 1:
        
        if (n < 50)
        {
          printf("Запись №%d:\n", n+1);
          vvod(&A[n]);
          n++;
        }
        else
          printf("\aНет памяти!\n");
        system("pause");
        break;  
    
    case 2: 
    
        if (n < 50)
        {
          k = dobav_number(n) - 1;
          
        if (k==-1) 
        {
            printf("Записи отсутствуют!\n");
            system("pause");
            break;
        }
          
        if (k >= 0)
          {
            for (i = n-1; i >= k; i--)
                A[i+1] = A[i];
                printf("\nВведите информацию для записи №%d:\n\n", k+1);
                vvod(&A[k]);        
          }
          n++;
        }
        else
          system("pause");
          printf("\aНет памяти!\n");
        break;
 
    case 3:
 
        k = udal_number(n) - 1;
        
        if (k==-1) 
        {
            printf("Записи отсутствуют!\n");
            system("pause");
            break;
        }
        
        else
        {
          for (;k<n;k++)
          A[k]=A[k+1];
          n--;
        }
        
        system("pause");
        break;
        
    case 41:
 
        k = vivod_number(n);
        
        if (k == 0) {printf("Записи отсутствуют!\n");}
        
        if (k == 1) {printf("\nВот информация о записи №1:\n\n"); vivodinfo(&A[1]);}
        
        if (k > 1) {printf("\nВот информация о записи №%d:\n\n", k);vivodinfo(&A[k-1]);}
            
        system("pause");
        break;
        
    case 42:
        
        if (n == 0) {printf("Записи отсутствуют!\n");}
        
        else 
        {
        fflush(stdin);
        printf("Введите видимую величину звезды: ");
        scanf("%lg", &zv);
        poisk(A, n, zv);
        }
        
        system("pause");
        break;      
    
    case 43:
           
        if (n == 0) {printf("Записи отсутствуют!\n");}
        
        else 
        {
          
        for (i=0; i<n; i++)
            {
            printf("\n*** Запись № %i ***\n", i+1); 
            vivodinfo(&A[i]);
            }
        }     
          
        system("pause");
        break;  
        
    case 5:
        
        if (n == 0) {printf("Записи отсутствуют!\n");}
        
        if (n > 0) {
            sort(A, n);
            printf("Сортировка успешно выполнена!\n");
                   }
             
        system("pause");
        break;  
        
    case 6:
        
        system("cls");
        save(&A, n);
        system("cls");
        printf("Записывание в файл выполнена успешно!\n");
        
        system("pause");
        break;  
        
    case 7:
        
        system("cls");
        zagruzka(&A);
    
        printf("Загразка из файла выполнена успешно!\n");
        
        system("pause");
        break;  
            
    case 9:
        
        return 0;
        
        
    default:
        printf("\aОперация не найдена! Повторите попытку \n");
        system("pause");
        break;
    
    }   
 }
                                                                                                                                                
    system("pause");
    return 0;
}

&n это адрес переменной n, а не байты значения.

Надо число преобразовывать в байты.
Как-то так: https://stackoverflow.com/a/3784478/964478

Или просто используйте unsigned char (1 байт) вместо int для количества если не планируете больше 255 звезд. :soidet:


Ну и

Начните хотя бы с переименовывания zagruzka в zagruzit, а zagruzit в load :slight_smile:

И я бы передавал имя файла в эти функции вместо ввода прямо в них.
Статья на эту тему (код на JavaScript, но большинство идей применимы ко всему и там есть объяснения в тексте):

Я бы zagruzka переименовал в load

Так и я о том )

:confounded: :weary: может есть способ легче?(((! уже второй день сижу над этим((( зато точно понял, что в динамической памяти нужно срочно разбираться… помогите мне, пожалуйста, ее допилить :cold_sweat: буду очень благодарен!

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

struct zv_koordinati 
{
double ugol;
int chas, min;	/* координаты на небосклоне (15° 23 ч 27 мин) */
};

struct rasdozamli 
{
double ras; 
int godkm;	/* расстояние до Земли ( в св. годах или в км) */
};

struct zvezda 
{
char zv_name[20];			/* название (Солнце) */
double zv_velichina;		/* видимая величина (-26,74) */
struct zv_koordinati k; 
struct rasdozamli l;
};

void vivodinfo(const struct zvezda *p)
{
	printf("Название звезды: \t %s \n", p -> zv_name);
	printf("Видимая величина: \t %lg \n", p -> zv_velichina);
	printf("Расстояние до Земли: \t %lg %s \n", p -> l.ras, (p -> l.godkm ? "св.лет" : "км"));
	printf("Координаты на небосклоне: \t %lg°   %d ч %d мин \n\n", p -> k.ugol, p -> k.chas, p -> k.min);		
}

void vvodzvkoordinati(const struct zv_koordinati *p)
{	
	fflush(stdin);
	printf("\nУгол:\t");
	scanf("%lg", &p->ugol);
	while (p->ugol < -90 || p->ugol > 90) {
	printf("\nОшибка. Введите угол ещё раз (от -90 до 90)!\n");
	printf("\nУгол:\t");
	fflush(stdin);
	scanf("%lg", &p->ugol);	
	}

	fflush(stdin);
	printf("Часы:\t");
	scanf("%d", &p->chas);
	while (p->chas < 0 || p->chas > 23) {
	printf("\nОшибка. Введите часы ещё раз (формат - 24 часа)!\n");
	printf("Часы:\t");
	fflush(stdin);
	scanf("%d", &p->chas);	
	}

	fflush(stdin);
	printf("Минуты:\t");
	scanf("%d", &p->min);
	while (p->min < 0 || p->min > 59) {
	printf("\nОшибка. Введите минуты ещё раз (в часе 60 минут)!\n");
	printf("Минуты:\t");
	fflush(stdin);
	scanf("%d", &p->min);	
	}
}

void vvod(struct zvezda *p) 
{
	fflush(stdin);
	printf("Название звезды:\t");
	scanf("%s", &p -> zv_name);
	fflush(stdin);
	printf("Видимая величина:\t");
	scanf("%lg", &p -> zv_velichina);
	fflush(stdin);
	printf("Расстояние до Земли:\t");
	scanf("%lg", &p -> l.ras);
	fflush(stdin);
	printf("\nРасстояние до Земли записано в световых годах или километрах?\n");
	printf("Если в св. годах, то нажмите - 1, если в километрах нажмите - 0: ");
	scanf("%d", &p -> l.godkm);
	while (p->l.godkm > 1 || p->l.godkm < 0) {
	printf("\nОшибка. Повторите попытку!\n");
	printf("Введите 1 (св года) или 0 (км): ");
	fflush(stdin);
	scanf("%d", &p->l.godkm); }
	fflush(stdin);
	printf("\nКоординаты на небосклоне:\t");
	vvodzvkoordinati(&p -> k);
}

void poisk(const struct zvezda A[], int n, double zv1)
{
	int i, k;
    for (i = 0, k = 0; i < n; i++)
    if (A[i].zv_velichina == zv1)
    {
      printf("\n*** Запись № %d ***\n", ++k);
      vivodinfo(&A[i]);
    }
  	printf("\nНайдено %d записей из %d.\n", k, n);	
}

int dobav_number(int n) 
{
	int k;
	if (n == 0){return 0;}
	
	if (n == 1){return 1;}
	
	fflush(stdin);
	printf("Укажите номер записи для вставки новой записи (от 1 до %d): ", n);
    scanf("%d", &k); 
	while (k < 1 || k > n) {
	printf("Ошибка. Проверьте правильность ввода и повторите попытку!\n");
	printf("Укажите номер записи для вставки (от 1 до %d): ", n);
	fflush(stdin);
	scanf("%d", &k);	   }
	
    return k;   
}

int udal_number(int n) 
{
	int k;
	
	if (n == 0){return 0;}
	
	if (n == 1){printf("Запись №1 удалена!\n\n");return 1;}
	
	fflush(stdin);
	printf("Укажите номер записи, которую необходимо удалить (от 1 до %d): ", n);
    scanf("%d", &k); 
	while (k < 1 || k > n) {
	printf("Ошибка. Проверьте правильность ввода и повторите попытку!\n");
	printf("Укажите номер записи, которую необходимо удалить (от 1 до %d): ", n);
	fflush(stdin);
	scanf("%d", &k);       }
	
	printf("Запись №%d удалена!\n\n", k);
	
    return k;  	
}

int vivod_number(int n)
{
	int k;
	if (n == 0){return 0;}
	
	if (n == 1){return 1;}
	
	fflush(stdin);
	printf("Укажите номер записи для её поиска (от 1 до %d): ", n);
    scanf("%d", &k); 
	while (k < 1 || k > n) {
	printf("Ошибка. Проверьте правильность ввода и повторите попытку!\n");
	printf("Укажите номер записи для её поиска (от 1 до %d): ", n);
	fflush(stdin);
	scanf("%d", &k);       }
	
	return k;
}

int sravnenie(const struct zvezda *p1, const struct zvezda *p2)
{
	double rast1, rast2;
	
	if (p1 -> l.godkm)
	rast1 = p1->l.ras*9460730472580820.0;
	else
	rast1 = p1->l.ras;
	
	if (p2 -> l.godkm)
	rast2 = p2->l.ras*9460730472580820.0;
	else
	rast2 = p2->l.ras;
	
	return rast1 > rast2 ||	rast1 == rast2;		
}

void sort(struct zvezda A[], int n)
{
  int i, j;
  for (j = 1; j < n; j++)
    for (i = 0; i < n-j; i++)
      if (sravnenie(&A[i], &A[i+1]))
      {
        struct zvezda temp;
        temp = A[i];
        A[i] = A[i+1];
        A[i+1] = temp;
      }
}

int save (struct zvezda *p, int n)
{
	FILE *file;
	char fname[20];
	char *c;
	int size = n * sizeof(struct zvezda); // количество записываемых байтов
	int i;

	printf("Введите имя файла, в который будут сохранены существующие записи: ");
	scanf ("%s", fname);
	file=fopen(fname, "wb");
	if (file == NULL)
	{
		printf("Возникла ошибка!");
		return(0);
	}
	
	//записываем количество структур c = (char *)&n;
	for (i = 0; i < sizeof(int); i++)
	{
		putc(*c++, file);
	}
	
	//посимвольно записываем в файл все структуры
	c = (char *)p; 
	
	for (i = 0; i < size; i++) 
	{
		putc(*c, file);	
		c++;
	}
	
	fclose(file);
	return 0;
}

int load (struct zvezda *p)
{
	FILE *file;
	char fname[20];
	char *c;
	int m = sizeof(int);
	int i, n; 
	
	//выделяем память для количества данных
	int *pti = (int *)malloc(m); 
	
	printf("Введите имя файла, из которого будут загружены записи: ");
	scanf ("%s", fname);
	file=fopen(fname, "r");
	if (file == NULL)
	{
		printf("Возникла ошибка!");
		return(0);
	}
	
	//считываем количество структур
	c = (char *)pti; 
	while (m > 0)
	{
		i = getc(file);
		if (i == EOF) break;
		*c = i;
		c++;
		m--;
	}	
	//получаем число элементов
	n = *pti; 
	
	struct zvezda *ptr = (struct zvezda *) malloc(n * sizeof(struct zvezda));
	c = (char *)ptr;
	
	while ((i= getc(file)) != EOF)
    {
        *c = i;
        c++;
    }
 
    free(pti);
    free(ptr);
    fclose(file);
    return 0;
}

int main()
{
	struct zvezda A[50];
	int number, n=0, i, k, d=0;
	double zv;

	system("chcp 1251 > nul");
	
	while (d<2) {
		
	system("cls");
	
	 printf("___________________________________________________________________\n"
			"********************|-----------MENU----------|********************\n"
			"*******************************************************************\n"
			"*   1. Добавить запись                                            *\n"
			"*   2. Вставить запись                                            *\n"
			"*   3. Удалить запись                                             *\n"
			"*   4. Просмотреть запись                                         *\n"
			"*        41 - по указанному номеру                                *\n"
			"*        42 - по видимой величине                                 *\n"
			"*        43 - все записи                                          *\n"
			"*   5. Сортировать записи (по возрастанию расстояния до Земли)    *\n"
			"*   6. Сохранить записи в файл                                    *\n"
			"*   7. Загрузить записи из файла                                  *\n"
			"*   ???                                                           *\n"
			"*   9. Выйти из меню                                              *\n"
			"*******************************************************************\n>> ");

	fflush(stdin);
	scanf("%d", &number);
	
	switch (number) {
		
	case 1:
		
        if (n < 50)
        {
          printf("Запись №%d:\n", n+1);
          vvod(&A[n]);
          n++;
        }
        else
          printf("\aНет памяти!\n");
        system("pause");
        break;	
	
	case 2:	
	
		if (n < 50)
        {
          k = dobav_number(n) - 1;
          
        if (k==-1) 
       	{
       		printf("Записи отсутствуют!\n");
       		system("pause");
       		break;
		}
          
        if (k >= 0)
          {
			for (i = n-1; i >= k; i--)
       			A[i+1] = A[i];
			    printf("\nВведите информацию для записи №%d:\n\n", k+1);
            	vvod(&A[k]); 	 	
          }
		  n++;
        }
        else
          system("pause");
          printf("\aНет памяти!\n");
        break;

	case 3:
 
       	k = udal_number(n) - 1;
       	
       	if (k==-1) 
       	{
       		printf("Записи отсутствуют!\n");
       		system("pause");
       		break;
		}
		
		else
		{
		  for (;k<n;k++)
          A[k]=A[k+1];
		  n--;
		}
		
        system("pause");
        break;
		
	case 41:

		k = vivod_number(n);
		
		if (k == 0) {printf("Записи отсутствуют!\n");}
		
		if (k == 1) {printf("\nВот информация о записи №1:\n\n"); vivodinfo(&A[1]);}
		
		if (k > 1) {printf("\nВот информация о записи №%d:\n\n", k);vivodinfo(&A[k-1]);}
			
	   	system("pause");
	    break;
		
	case 42:
		
		if (n == 0) {printf("Записи отсутствуют!\n");}
		
		else 
		{
		fflush(stdin);
		printf("Введите видимую величину звезды: ");
		scanf("%lg", &zv);
	    poisk(A, n, zv);
	    }
	    
	   	system("pause");
        break;		
	
	case 43:
           
		if (n == 0) {printf("Записи отсутствуют!\n");}
		
		else 
		{
		  
       	for (i=0; i<n; i++)
	    	{
	    	printf("\n*** Запись № %i ***\n", i+1);	
	    	vivodinfo(&A[i]);
			}
		}	  
		  
	   	system("pause");
        break;	
		
	case 5:
		
		if (n == 0) {printf("Записи отсутствуют!\n");}
		
		if (n > 0) {
			sort(A, n);
			printf("Сортировка успешно выполнена!\n");
		           }
		     
		system("pause");
	    break;	
		
	case 6:
		
		system("cls");
		save(&A, n);
		system("cls");
		printf("Записывание в файл выполнена успешно!\n");
		
		system("pause");
	    break;	
		
	case 7:
		
		system("cls");
		load(&A);
	
		printf("Загразка из файла выполнена успешно!\n");
		
		system("pause");
	    break;	
			
	case 9:
		
        return 0;
		
		
	default:
        printf("\aОперация не найдена! Повторите попытку \n");
        system("pause");
        break;
	
	}	
 }
																																				
	system("pause");
	return 0;
}

Тут c вообще не инициализировано.

image

Я бы кстати эту переменную переименовал бы в bytes

И я ж писал уже про количество:

int save (struct zvezda *p, int n)
{
	FILE *file;
	char fname[20];
	char *bytes;
	unsigned char size = n * sizeof(struct zvezda); // количество записываемых байтов
	int i;

	printf("Введите имя файла, в который будут сохранены существующие записи: ");
	scanf ("%s", fname);
	file=fopen(fname, "wb");
	if (file == NULL)
	{
		printf("Возникла ошибка!");
		return(0);
	}
	
	//записываем количество структур 
	bytes = (char *)&n;
	for (i = 0; i < sizeof(unsigned char); i++)
	{
		putc(*bytes++, file);
	}
	
	//посимвольно записываем в файл все структуры
	bytes = (char *)p; 
	
	for (i = 0; i < size; i++) 
	{
		putc(*c, file);	
		bytes++;
	}
	
	fclose(file);
	return 0;
}

int load (struct zvezda *p)
{
	FILE *file;
	char fname[20];
	char *c;
	int m = sizeof(int);
	int i, n; 
	
	//выделяем память для количества данных
	int *pti = (int *)malloc(m); 
	
	printf("Введите имя файла, из которого будут загружены записи: ");
	scanf ("%s", fname);
	file=fopen(fname, "r");
	if (file == NULL)
	{
		printf("Возникла ошибка!");
		return(0);
	}
	
	//считываем количество структур
	c = (char *)pti; 
	while (m > 0)
	{
		i = getc(file);
		if (i == EOF) break;
		*c = i;
		c++;
		m--;
	}	
	//получаем число элементов
	n = *pti; 
	
	struct zvezda *ptr = (struct zvezda *) malloc(n * sizeof(struct zvezda));
	c = (char *)ptr;
	
	while ((i= getc(file)) != EOF)
    {
        *c = i;
        c++;
    }
 
    free(pti);
    free(ptr);
    fclose(file);
    return 0;
}

А, не, это все-таки будет работать, но как написано по ссылке

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

Но в любом случае сделайте пока просто с одним байтом (тип n поменяйте на unsigned char), тогда просто без циклов один putc при записи, один getc при чтении. Когда заработает, можно попробовать int.

Ну и в любой непонятной ситуации добавляйте отладочный вывод (выводите все переменные в консоль).

Например, как-то так можно вывести байты (например, чтобы убедиться, что при сохранении и загрузке они совпадают):

#include <stdio.h>

int main()
{
    int n = 42;
	char* bytes = (char *)&n;
	for (int i = 0; i < sizeof(int); i++)
	{
	    char byte = *bytes++;
	    
		printf("%x ", byte);
	}

    return 0;
}

https://onlinegdb.com/HJzVbva38

:sob:

А что я здесь неправильно сделал?

int save (struct zvezda A[], int n)
{
	FILE *file;
	char fname[20];
	int  i;

	printf("Введите имя файла, в который будут сохранены существующие записи: ");
	scanf ("%s", fname);
	file=fopen(fname, "w");
	if (file == NULL)
	{
		printf("Возникла ошибка!");
		return(0);
	}
	
	for (i = 0; i != n; i++) 
	{
		fprintf(file, "%s\n", A[i].zv_name);
		fprintf(file, "%lg %lg %s %lg %d %d", A[i].zv_velichina, A[i].l.ras, (A[i].l.godkm ? "св.лет" : "км"), A[i].k.ugol, A[i].k.chas, A[i].k.min);
	}
	
	fclose(file);
	return 0;
}

int load (struct zvezda A[], int n)
{
	FILE *file;
	char fname[20];
	int i;
	
	printf("Введите имя файла, из которого будут загружены записи: ");
	scanf ("%s", fname);
	file=fopen(fname, "r");
	if (file == NULL)
	{
		printf("Возникла ошибка!");
		return(0);
	}
	
	for (i = 0; i != n; i++) 
	{
		fgets(A[i].zv_name, 20, file);
		fscanf(file, "%lg%lg%s%lg%d%d", A[i].zv_velichina, A[i].l.ras, (A[i].l.godkm ? "св.лет" : "км"), A[i].k.ugol, A[i].k.chas, A[i].k.min);
	}
	printf("%s %lg %lg %s %lg %d %d", A[i].zv_name, A[i].zv_velichina, A[i].l.ras, (A[i].l.godkm ? "св.лет" : "км"), A[i].k.ugol, A[i].k.chas, A[i].k.min);

        fclose(file);
        return 0;
}

Так а результат-то какой?) Что происходит?

Записывается так, как и задумано.

а читается немного вообще не так…

Ребята, ну помогите, пожалуйста, составить эти две функции сохранения и загрузки массива структур в файл на основе: https://metanit.com/cpp/c/7.3.php!

а если пробелы добавить?)

Откуда известно сколько элементов в файле до его чтения?

n по идее надо каким-то образом получать при чтении файла (либо читать сохраненное число, либо считать сколько элементов успешно прочиталось до конца файла) и возвращать из этой функции.


Текст из консоли лучше копировать, а не скриншотить, на то он и текст :wink:

csma в выводе похоже на мусор, что видимо означает, что чтение завершилось неудачно и в неинициализированном str остался мусор.
Проверяйте результат fgets + ferror, perror.
http://www.cplusplus.com/reference/cstdio/fgets/

On success, the function returns str .
If the end-of-file is encountered while attempting to read a character, the eof indicator is set (feof). If this happens before any characters could be read, the pointer returned is a null pointer (and the contents of str remain unchanged).
If a read error occurs, the error indicator (ferror) is set and a null pointer is also returned (but the contents pointed by str may have changed).