Я пишу функцию (*rwObjects()
), которая будет читать отформатированный файл и сохранять его строки, по одному объекту за раз. К сожалению, для моих исследований есть ограничение - stdio.h, stdlib.h и string.h - это практически все, что я могу использовать.
Вот проблема: всякий раз, когда я запускаю код, когда он доходит до fclose(input)
, VS17 говорит, что мой проект активировал точку останова, а затем открывает вкладку с надписью «wntdll.pdb не загружен» или что-то в этом роде.
Вопрос в следующем: как мне не активировать точку останова и правильно закрыть файл? Или, если проблема не в файле, то где она?
Код (С):
#define _CRT_SECURE_NO_WARNINGS
#define cnCOUNTRY_LENGTH 3
#define cnOBJECT_NAME_LENGTH 30
#define cnOBJECT_MAX 1000
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//--Поле объекта objectType--
//Country (0) - строка названия страны
//ObjectName (1) - строка названия объекта
//Square (2) - площадь объекта
//Error (3) - ошибка в содержании строки
typedef enum IOOptions {Country, ObjectName, Square, Error} IOType;
//--Тип обрабатываемых объектов--
//char Country - строка названия страны
//char ObjectName - строка названия объекта
//int Square - площадь объекта
typedef struct object {
char Country[cnCOUNTRY_LENGTH];
char ObjectName[cnOBJECT_NAME_LENGTH];
int Square;
} objectType;
//--Копирование текущего элемента строки objects.txt--
//strMod - Строка, в которую идёт копирование
//strPos - Позиция в считываемой строке
//strBlueprint - Строка, из которой идёт копирование
//writeType - Поле объекта objectType. При "Country" - переводит вводимые символы в верхний регистр ('a' -> 'A' и т.д.)
void copyInputStr(char *strMod, int *strPos, char *strBlueprint, IOType writeType) {
for (*strPos; *strBlueprint != ' ' && *strBlueprint != '\n' && *strBlueprint != NULL; *strPos = *strPos + 1) {
*strMod = *strBlueprint;
if (writeType == Country) toupper(*strMod);
strBlueprint++; strMod++;
}
}
//--Запись текущего элемента строки objects.txt в текущий объект--
//strInput - Строка, из которой идёт запись
//objectOutput - Объект, в который идёт запись
//writeType - Поле объекта, в которое идёт запись
void writeObject(char *strInput, objectType *objectOutput, IOType writeType) {
if (writeType == Country)
strcpy(objectOutput->Country, strInput);
else if (writeType == ObjectName)
strcpy(objectOutput->ObjectName, strInput);
else if (writeType == Square)
objectOutput->Square = atoi(strInput);
else printf("Error 1. Invalid parameters");
}
//--Чтение objects.txt и запись в массив objectType--
//Возвращает указатель на первый элемент массива объектов
objectType *rwObjects() {
FILE *input = fopen("objects.txt", "r");
char objectQttStr[4], objectStr[38];
fgets(objectQttStr, 4, input);
objectType *objectList = (objectType *)malloc(atoi(objectQttStr)), *currentObject = objectList;
currentObject = (objectType *)malloc(atoi(objectQttStr));
for (int i = 0; i < atoi(objectQttStr); i++) {
fgets(objectStr, 38, input);
IOType inputType = Country;
for (int j = 0; objectStr[j] != NULL && objectStr[j] != '\n'; j++) {
char strBuf[cnOBJECT_NAME_LENGTH];
memset(&strBuf, 0, sizeof(strBuf));
copyInputStr(&strBuf, &j, &objectStr[j], inputType);
writeObject(&strBuf, currentObject, inputType);
inputType++;
}
currentObject++;
}
fclose(input); //this is where it happens
return objectList;
}
void main() {
objectType *objectList = rwObjects();
printf("");
}
Это запутанная программа, но я не нашел другого способа следовать гребаным правилам, так что давайте отложим в сторону стиль кодирования, хорошо?
Кроме того, я знаю, что если он запустится успешно, ничего не произойдет - так задумано. Это еще не закончено.
РЕДАКТИРОВАТЬ: Не беспокойтесь о достоверности входных данных. Все форматирование входных данных явно указано в задании, поэтому никаких проверок не требуется. Тем не менее, для любопытных, вот:
объекты.txt:
3
USA WelfareArrangement 120
Rus PoiskZemli 30
usa asdfEstate 1
РЕДАКТИРОВАТЬ 2: В тот момент, когда я перестал использовать malloc, все было в порядке. Вопрос в том, почему именно это было такой проблемой, и как мне создать массив точного размера, который мне нужен, вместо создания максимального размера каждый раз, если не с помощью malloc?
objectStr[j] != NULL
выглядит так, будто код сравниваетchar
с указателем. Вместо этого порекомендуйтеobjectStr[j] != '\0'
. - person chux - Reinstate Monica   schedule 19.12.2017input
, может быть, вcopyInputStr
? - person David Schwartz   schedule 19.12.2017fgets(objectStr, 38, input);
. - person chux - Reinstate Monica   schedule 19.12.2017fgets(objectQttStr, 4, input);
выглядит довольно маленьким для целого числа. - person chux - Reinstate Monica   schedule 19.12.2017