Аварийное завершение программы - C (СИ) (153295)
Формулировка задачи:
В общем, благодаря советам здешних форумчан, я таки осилил небольшую программку на малознакомом мне Си (я как то больше шарп и делфи), имитирующую систему контроля версий. Суть в чем - создаем файл, руками в него что-то пишем, сохраняем в одноименной созданной папке. Потом при след запуске руками же выбираем этот же файл, редактируем и в итоге сам файл переписывается и создается его копия с номером ревизии. Все хорошо и все работает, НО при завершении программы в ветке переписывания файла происходит ошибка (хотя файл переписывается и сохраняется). Трассировал сам, пробовал разные варианты, но причину так и не отловил. Код (порядком кривой и некрасивый, но все же):
P.S. Компилятор от с++, поэтому int main() и пр. Заранее спасибо.
#include <stdio.h> #include <stdlib.h> #include <conio.h> #include <dirent.h> #include <direct.h> #include <string.h> const int MAX_LENGTH = 255; //максимальная длина строки const int ESC = 27; //код клавиши Esc FILE *fn; //указатель на файл int open_file(FILE **f, char *name, const char *type) { if (((*f) = fopen(name,type)) == NULL) //открываем файл { perror(name); //если не получилось - генерируем ошибку system("pause"); return 1; //выходим из текущей итерации программы } else return 0; } void write_to_file(FILE **f, char *name) //запись в файл с именем name { if (open_file(f,name,"w") != 0) return; printf("Введите содержимое нового файла (Esc для окончания ввода):\n"); char *fstring = (char*)malloc(MAX_LENGTH); do { char c = getch(); if (c == ESC) break; //ввод производится до нажатия пользователем Esc scanf("%s",fstring); //прочитали строку fprintf(*f,fstring); //записали ее в файл fprintf(*f,"\n"); //добавили в файл символ переноса строки } while (true); printf("Файл %s успешно записан.\n",name); fclose(*f); //закрываем файл } void make_a_copy(FILE **f, char *name, int revision) { char *new_name = (char*)malloc(MAX_LENGTH); strcpy(new_name,name); sprintf(new_name, "%s_%d",name,revision); //strncat(new_name,ch,1); //добавили к имени нашего файла _ и номер ревизии FILE *fnew; if ((open_file(f,name,"r") != 0) || (open_file(&fnew,new_name,"w")!=0)) return; char c; while((c = fgetc(*f)) != EOF) fputc(c, fnew); fclose(*f); fclose(fnew); printf("Копия файла с номером ревизии %d успешно создана.\n",revision); } void create_new_file(FILE **f) //создание нового файла { DIR *dir; printf("Введите имя нового файла: "); char *name = (char*)malloc(MAX_LENGTH); scanf("%s",name); //чтение имени char *folder_name = (char*)malloc(MAX_LENGTH); strcpy(folder_name,name); strncat(folder_name,"/",1); //добавляем к имени слэш для работы с директорией if (mkdir(name) == 0) //пытаемся создать каталог для версий файла { printf("Каталог для хранения версий файла %s успешно создан.\n",name); //если такого каталога еще нет strncat(folder_name,name,strlen(name)); //добавили к имени каталога одноименный файл write_to_file(f,folder_name); //создали и записали файл } else //если каталог, а значит и файл, уже есть { printf("Файл %s уже существует.\n Желаете ли вы его перезаписать?\n",name); printf("Введите y - для продолжения, n - для отмены.\n"); printf("Ваш выбор : "); char *choice; scanf("%s",choice); //прочитали выбор пользователя if (strcmp(choice,"y") == 0) //если да { int count = -2; //кол-во файлов в каталоге, а -2 потому что не считаются . и .. (текущий каталог и наверх) dir = opendir(folder_name); //открыли каталог strncat(folder_name,name,strlen(name)); //добавили к имени каталога одноименный файл struct dirent *dp; while (((dp = readdir(dir)) != NULL)) //пока в каталоге есть непрочитанные файлы { if (strcmp(dp->d_name, name)== 0) //если найден главный файл (текущая версия) { write_to_file(f,folder_name); //открыли для записи, переписали } count++; //если файл еще не нашли - увеличили счетчик } if (count >= 1) //если у файла уже есть предыдущие версии { //make_a_copy(f,folder_name,count); //создали копию с номером текущей ревизии } closedir(dir); //закрыли директорию } else if (strcmp(choice,"")!=0) { printf("Неверный код выбора."); } } } int main() { create_new_file(&fn); getch(); return 0; }
Решение задачи: «Аварийное завершение программы»
textual
Листинг программы
char *choice; scanf("%s",choice);
Объяснение кода листинга программы
- Объявляется переменная типа char* с именем choice, которая будет хранить введенную пользователем строку.
- Пользователю предлагается ввести строку с помощью функции scanf, в которую передается форматная строка
%s
и адрес переменной choice. - Функция scanf считывает введенную пользователем строку и сохраняет ее в переменной choice.
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д