- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在编写一个函数 (*rwObjects()
),它将读取格式化文件并保存它的字符串,一次一个对象。不幸的是,它对我的研究有限制 - stdio.h、stdlib.h 和 string.h 几乎是我可以使用的所有内容。
问题是:每当我运行代码时,当它到达 fclose(input)
时,VS17 说我的项目触发了一个断点,然后打开一个选项卡,上面写着“wntdll.pdb not加载”或其他东西。
问题是:如何不触发断点并正确关闭文件?或者,如果问题不在文件中,那么它在哪里?
代码(C):
#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,我将如何创建一个我需要的确切大小的数组,而不是每次都创建最大大小?
最佳答案
第一个问题:
objectType *objectList = (objectType *)malloc(atoi(objectQttStr)), *currentObject = objectList;
currentObject = (objectType *)malloc(atoi(objectQttStr));
malloc
函数分配给定数量的字节。所以如果你有 5 个对象,你只分配 5 个字节。这对您的结构来说还不够。这会导致您写入超过调用 undefined behavior 的已分配内存的末尾。 .
如果你想让它为特定数量的对象分配空间,你需要乘以对象大小:
objectType *objectList = malloc(sizeof(*objectList)*atoi(objectQttStr));
此外,don't cast the return value of malloc
.
您还可以将 currentObject
分配给与 objectList
相同的值,然后使用单独的内存分配覆盖它。所以去掉第二个 malloc
。
第二个问题:
memset(&strBuf, 0, sizeof(strBuf));
copyInputStr(&strBuf, &j, &objectStr[j], inputType);
writeObject(&strBuf, currentObject, inputType);
您的copyInputStr
和writeObject
函数需要一个char *
,但是您传入了strBuf
的地址类型为 char (*)[30]
的数组。在这里去掉地址运算符:
memset(strBuf, 0, sizeof(strBuf));
copyInputStr(strBuf, &j, &objectStr[j], inputType);
writeObject(strBuf, currentObject, inputType);
第三个问题:
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++;
}
}
当您复制 strMod
中的字符时,您不会在末尾添加空字节。 C 中的字符串是一个以 null 结尾的字符数组,因此您最终得到的不是字符串,而只是一个字符数组。当您稍后对该数组调用 strcpy
时,该函数找不到空字节,因此它会一直读取直到找到为止。这会导致函数读取未初始化的字节和/或读取超过数组末尾的内容,这将再次调用未定义的行为。
在循环后添加空终止字节。此外,toupper
函数的结果未分配给任何内容,因此它什么也不做。您需要将其分配回 *strMod
:
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) *strMod = toupper(*strMod);
strBlueprint++; strMod++;
}
*strMod = 0;
}
关于C - fclose() 触发断点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47893005/
有没有办法在clojurescript中创建断点? 在 repl 或 chromes native 调试器中。 我试过 (js* "debugger") 这会返回 SyntaxError: Unexp
我有一个断点列表,每次调试特定程序时我都想添加这些断点。 有没有办法可以将所有断点信息放在一个文件中并在每个调试 session 开始时使用它?换句话说,我可以在我发出“运行”命令之前,向 GDB 提
我们能否在函数上设置 GDB 断点,使其仅在函数参数与指定值匹配时才中断?例如 int foo(int i) { return i*i; } int main() { foo(0); ....
我的应用程序当前在启动时崩溃,我只有一个 MainActivity 类,我正在尝试找出导致它的原因 我发现有多个Log Log.v();//详细 Log.d();//调试 Log.i();//信息 L
我在 Eclipse Helios 和 Mac OS X 最后的 Leopard 中工作,同时处理多个项目。我在项目 1 中设置了断点并且很好。项目 2 是项目 1 的分支,因此包含类似的文件。当我尝
当我在我的应用程序中单击一个按钮时,将执行一系列 Javascript 代码,在这种特殊情况下,我单击“取消”按钮以关闭当前打开的模式窗口。这close按钮在 HTML 上看起来像这样: Cancel
我已经在 objective-c 中编写了这个小程序。 int x; x=1; while (x<60) { self.jalo.text = [NSString stringWithForm
Twitter Boot strap 使用这些断点: 大显示:1200px默认值:980px平板电脑:768px手机:480px 一个客户说他们使用 1280px 作为他们的大屏幕断点。 这些是否有行
我正在尝试在 gdb 中设置断点以在 exit(0) 信号之前停止。我试过了: stop sigquit 虽然程序仍然没有停止就退出。如何为此设置断点? 最佳答案 您是否尝试在 exit 或 _exi
最新的 dart 编辑器支持调试和断点,它在静态 HTML 页面中工作。我有一个现有的后端 (Django),当我将“启动目标”设置为 URL 时,我无法让调试器工作。 我收到这个错误: An int
我有一个汇编程序,在不同的行上有几个标签。我需要设置一个 gdb在带有标签的行之后的两行断点。我怎么能在 gdb 中做到这一点不向程序添加额外的标签? 最佳答案 gdb支持在标签后添加 X 个字节的断
我有一个 IDE 断点 (delphi-xe),每次编译和运行程序时它都会重新出现。我该如何摆脱它。 Delphi 在哪里保存有关断点的信息? 更新: 1.断点未在“Breakpoints”面板中列出
breakpoints.up、breakpoints.down、breakpoints. Between 和 breakpoints.value 之间有什么区别> ?这段代码是什么意思,断点值在这里如
这个问题已经有答案了: Eclipse pausing without a breakpoint (6 个回答) 已关闭 8 年前。 我正在使用 Eclipse Juno。当我调试桌面应用程序时,调试
我是一名 CS 学生,所以我对编程还是很陌生。断点看起来非常酷并且对调试很有用,所以我决定尝试一下它们。 不幸的是,我真的不知道如何与他们合作。我在“记录断点和参数并自动继续”中添加了一个断点。程序到
使用 VStudio 2010 和 C# 我有一个名为哺乳动物的类。狗和猫继承自哺乳动物。 然而,一只特定的狗在呕吐,我需要找出原因。 我想在 Mammal 类中设置一个断点 - 但仅当 Dog 类正
编辑:我尝试在一个非常简单的程序上使用编辑器中内置的断点,它起作用了。所以我的代码(使用了大量的实例内存)和调试器可能对 nano 实例来说太多了。 我一直在命令行上使用 gdb 进行调试和设置断点。
我正在编写一个通过抛出异常从错误中恢复的应用程序。 然而,在调试时,我希望我的调试器在抛出异常之前在我的错误点停止。无论如何添加一些代码会导致GDB用某些代码中断执行。 我对 ARM 和 x86 架构
我正在为一个应用程序使用 MapKit。 我正在将信息存储在全局字典中,然后再次访问它们。 每个都使用文本+用户名+日期的键存储。此实例中的用户名变量包含字符串的日期和用户名 func mapView
在 PyCharm 中是否可以在外部 python 库中放置断点并单步执行? 对于上下文,我遵循 Django REST 框架快速入门指南:http://www.django-rest-framewo
我是一名优秀的程序员,十分优秀!