- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在开展一个学校项目,我需要从文件中获取矩阵的信息(高度、宽度、单元格状态)。像这样的事情:
30 40 /*height and width*/
3 /*nr of lines to read from the file*/
10 11 1 /*coordinates, and cell status (0,1,2)*/
10 12 1
10 13 2
由于某种原因,它不断在调试器中给我 SIGABRT 或损坏的双链表。我知道代码并不完美,但我开始修改它,看看是否能找到问题。
这是我的代码:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
int ***getFileLoad(char *fileName)
{
char strLines[5], strColumns[5], strCells[5], strTemp[3];
int i = 0, j = 0, k = 0, l = 0, lines = 0, columns = 0, cells = 0, intTemp = 0;
int ***array = NULL;
FILE *file = NULL;
file = fopen(fileName, "r"); /*opens file*/
if (file == NULL)
{
printf("Error opening file!\n");
exit(EXIT_FAILURE);
}
fscanf(file, "%s %s %s", &strLines, &strColumns, &strCells);
lines = atoi(strLines);
if (lines <= 0) /*lines*/
{
printf("Invalid value, lines!");
exit(EXIT_FAILURE);
}
columns = atoi(strColumns);
if (columns <= 0) /*columns*/
{
printf("Invalid value, columns!");
exit(EXIT_FAILURE);
}
cells = atoi(strCells);
if (cells <= 0) /*cells*/
{
printf("Invalid value, cells!");
exit(EXIT_FAILURE);
}
array = (int ***)malloc(sizeof(int **) * lines); /*allocating lines*/
if (array == NULL)
{
printf("No memory!");
exit(EXIT_FAILURE);
}
for (i = 0; i < columns; i++) /*allocating columns*/
{
array[i] = (int **)malloc(sizeof(int *) * columns);
if (array[i] == NULL)
{
printf("No memory!");
for (j = 0; j < i; j++)
{
free(array[j]);
}
free(array);
array = NULL;
exit(EXIT_FAILURE);
}
}
for (i = 0; i < lines; i++) /*allocating nr of cells*/
{
for (j = 0; j < columns; j++)
{
array[i][j] = (int *)malloc(sizeof(int) * cells);
if (array[i][j] == NULL)
{
printf("No memory!");
for (k = 0; k < i; k++)
{
for (l = 0; l < j; l++)
{
free(array[k][l]);
}
}
for (k = 0; k < i; k++)
{
free(array[k]);
}
free(array);
array = NULL;
exit(EXIT_FAILURE);
}
}
}
array[0][0][0] = lines;
array[0][0][1] = columns;
array[0][0][2] = cells;
for (i = 0; i < 1; i++) /*nr arrays*/
{
for (j = 1; j < cells + 1; j++) /*nr cells*/
{
for (k = 0; k < 4; k++) /*values from file*/
{
if (k == 3) /*getting to the next line*/
{
intTemp = fgetc(file);
if (intTemp == '\n' || intTemp == EOF)
{
continue;
}
else
{
while (intTemp != '\n' || intTemp != EOF)
{
intTemp = fgetc(file);
if (intTemp == '\n' || intTemp == EOF)
{
break;
}
}
}
}
else
{
fscanf(file, "%s", strTemp);
if (isdigit(strTemp))
{
intTemp = atoi(strTemp);
if (k == 0) /*accepting lines with values between1->lines*/
{
if (!(intTemp >= 1 && intTemp < lines))
{
printf("Invalid value!");
exit(EXIT_FAILURE);
}
else
{
array[i][j][k] = intTemp;
}
}
else if (k == 1) /*accepting columns with values between 1->columns*/
{
if (!(intTemp >= 1 && intTemp < columns))
{
printf("Invalid value!");
exit(EXIT_FAILURE);
}
else
{
array[i][j][k] = intTemp;
}
}
else if (k == 2) /*accepting cells with values between 0->2*/
{
if (!(intTemp >= 0 && intTemp < 3))
{
printf("Invalid value!");
exit(EXIT_FAILURE);
}
else
{
array[i][j][k] = intTemp;
}
}
}
}
}
}
}
intTemp = fgetc(file); /*checking for EOF*/
if (intTemp != EOF)
{
printf("Impossible reading every value!");
exit(EXIT_FAILURE);
}
fclose(file);
return array;
}
最佳答案
基本问题与这些类型的问题通常相同 - 您使自己的任务对自己来说过于复杂,方法是:
在一个巨大的函数中塞入太多内容,而不是将其分解成易于消化的部分
使用笨拙的文件读取函数,例如 fscanf()
和 fgetc()
重复代码,包括可以移至单独函数的错误检查代码
所有这些都使得跟踪你正在做的事情变得极其困难,因为你的庞大函数读起来就像意大利面条一样,而且你对它没有大局观。它变成了一大堆代码,其中任何一个都可能是错误的。
以下是一些操作示例,您可以并且应该为其设置单独的功能:
创建矩阵
摧毁你的矩阵
设置矩阵单元格的值
获取矩阵单元格的值
从文件中获取一组坐标
从文件中获取尺寸
获取文件的行数
此外,您应该将相关值包装在数据结构中,例如矩阵的维度(以及矩阵数据本身的维度)和坐标。
这是一个更好的编写方法的简单示例。例如,看看 main()
函数,看看它是多么容易理解。如果您的代码易于理解且易于阅读,那么它就很容易维护,并且更容易发现(并避免)错误。
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define MAX_LINE_LENGTH 1024
/* Holds dimensions for a matrix */
struct dimensions {
int lines;
int columns;
int cells;
};
/* Holds a set of three-dimensional coordinates */
struct coords {
int x;
int y;
int z;
};
/* Holds a three-dimensional matrix */
struct matrix {
struct dimensions dim;
int *** lines;
};
void * xmalloc(const size_t sz);
void * xcalloc(const size_t nmemb, const size_t size);
struct matrix * matrixCreate(struct dimensions * dim);
void matrixDestroy(struct matrix * matrix);
void matrixSet(struct matrix * matrix, struct coords coord, const int value);
int matrixGet(struct matrix * matrix, struct coords coord);
FILE * openDataFile(const char * filename);
void getLineFromFile(FILE * fp, char * buffer, const size_t length);
struct dimensions getDimensionsFromFile(FILE * fp);
struct coords getCoordsFromFile(FILE * fp);
void validateCoords(struct matrix * matrix, struct coords coords);
int getSingleIntegerLine(FILE * fp);
int main(void)
{
/* Set up matrix and data file */
FILE * fp = openDataFile("matrix.dat");
struct dimensions dim = getDimensionsFromFile(fp);
const int numLines = getSingleIntegerLine(fp);
struct matrix * matrix = matrixCreate(&dim);
/* Populate matrix cells specified in file */
for ( size_t i = 0; i < numLines; ++i ) {
struct coords coords = getCoordsFromFile(fp);
validateCoords(matrix, coords);
matrixSet(matrix, coords, 1);
}
/* Test and print the value of some matrix cells */
struct coords coords[6] = {
{10, 11, 1},
{10, 11, 2},
{10, 12, 1},
{10, 12, 2},
{10, 13, 1},
{10, 13, 2}
};
for ( size_t i = 0; i < 6; ++i ) {
const int value = matrixGet(matrix, coords[i]);
printf("Value at %d, %d, %d: %d\n",
coords[i].x, coords[i].y, coords[i].z, value);
}
/* Clean up and exit */
matrixDestroy(matrix);
fclose(fp);
return 0;
}
void * xmalloc(const size_t sz)
{
void * p = malloc(sz);
if ( !p ) {
perror("couldn't allocate memory");
exit(EXIT_FAILURE);
}
return p;
}
void * xcalloc(const size_t nmemb, const size_t size)
{
void * p = calloc(nmemb, size);
if ( !p ) {
perror("couldn't allocate memory");
exit(EXIT_FAILURE);
}
return p;
}
struct matrix * matrixCreate(struct dimensions * dim)
{
int *** lines = xmalloc(dim->lines * sizeof *lines);
for ( size_t i = 0; i < dim->lines; ++i ) {
int ** columns = xmalloc(dim->columns * sizeof *columns);
for ( size_t j = 0; j < dim->columns; ++j ) {
int * cells = xcalloc(dim->cells, sizeof *cells);
columns[j] = cells;
}
lines[i] = columns;
}
struct matrix * matrix = xmalloc(sizeof *matrix);
matrix->lines = lines;
matrix->dim = *dim;
return matrix;
}
void matrixDestroy(struct matrix * matrix)
{
for ( size_t i = 0; i < matrix->dim.lines; ++i ) {
for ( size_t j = 0; j < matrix->dim.columns; ++j ) {
free(matrix->lines[i][j]);
}
free(matrix->lines[i]);
}
free(matrix->lines);
free(matrix);
}
void matrixSet(struct matrix * matrix, struct coords coords, const int value)
{
matrix->lines[coords.x][coords.y][coords.z] = value;
}
int matrixGet(struct matrix * matrix, struct coords coords)
{
return matrix->lines[coords.x][coords.y][coords.z];
}
FILE * openDataFile(const char * filename)
{
FILE * fp = fopen(filename, "r");
if ( !fp ) {
perror("couldn't open file");
exit(EXIT_FAILURE);
}
return fp;
}
void getLineFromFile(FILE * fp, char * buffer, const size_t length)
{
if ( !fgets(buffer, length, fp) ) {
fprintf(stderr, "Couldn't read dimensions from file.\n");
exit(EXIT_FAILURE);
}
}
struct dimensions getDimensionsFromFile(FILE * fp)
{
char buffer[MAX_LINE_LENGTH];
getLineFromFile(fp, buffer, MAX_LINE_LENGTH);
struct dimensions dim;
if ( sscanf(buffer, "%d %d", &dim.lines, &dim.columns) != 2 ) {
fprintf(stderr, "Couldn't read dimensions from file.\n");
exit(EXIT_FAILURE);
}
dim.cells = 3;
return dim;
}
struct coords getCoordsFromFile(FILE * fp)
{
char buffer[MAX_LINE_LENGTH];
getLineFromFile(fp, buffer, MAX_LINE_LENGTH);
struct coords coords;
if ( sscanf(buffer, "%d %d %d", &coords.x, &coords.y, &coords.z) != 3 ) {
fprintf(stderr, "Couldn't read coordinates from file.\n");
exit(EXIT_FAILURE);
}
return coords;
}
void validateCoords(struct matrix * matrix, struct coords coords)
{
bool valid = true;
if ( coords.x < 0 || coords.x >= matrix->dim.lines ) {
fprintf(stderr, "Invalid x coordinate: %d\n", coords.x);
valid = false;
}
if ( coords.y < 0 || coords.y >= matrix->dim.columns ) {
fprintf(stderr, "Invalid y coordinate: %d\n", coords.y);
valid = false;
}
if ( coords.z < 0 || coords.z >= matrix->dim.cells ) {
fprintf(stderr, "Invalid z coordinate: %d\n", coords.z);
valid = false;
}
if ( !valid ) {
exit(EXIT_FAILURE);
}
}
int getSingleIntegerLine(FILE * fp)
{
char buffer[MAX_LINE_LENGTH];
getLineFromFile(fp, buffer, MAX_LINE_LENGTH);
int value;
if ( sscanf(buffer, "%d", &value) != 1 ) {
fprintf(stderr, "Couldn't read single value from file.\n");
exit(EXIT_FAILURE);
}
return value;
}
使用示例文件输出:
paul@thoth:~/src/sandbox$ ./matrix
Value at 10, 11, 1: 1
Value at 10, 11, 2: 0
Value at 10, 12, 1: 1
Value at 10, 12, 2: 0
Value at 10, 13, 1: 0
Value at 10, 13, 2: 1
paul@thoth:~/src/sandbox$
关于c - SIGABRT 和损坏的双链表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34713665/
我的代码在使用 malloc 时遇到问题。直到一个小时前它一直运行良好。它导致这一行 temp2 = (Temp*)malloc(sizeof(Temp));
我的应用程序运行完美,没有任何问题。但是当我尝试调试它时,android studio 卡住了。所以我收到消息“等待调试器”,然后该消息消失,接下来我在模拟器中只看到黑屏。 我也收到了消息 SIGNA
我用 node-js 和 fluent-ffmpeg 编写了一个 node-js api: 'use strict'; require('babel-register'); const path =
我只是在过去一直工作的模拟器上运行我的代码。我真正为启动代码所做的唯一一件事就是设置用户默认值 NSUserDefaults *defaults = [NSUserDefaults standard
我遇到应用程序每次运行时都会在模拟器上崩溃。由于某种原因,他们收到一个中止信号(见附件截图)。最近才开始用,不知道是不是和10.8.4升级有关。 我刚刚基于“单一 View 应用程序”模板创建了一个新
我的应用程序中存在一个错误,使我发疯!尝试隐藏navigationController工具栏后,主线程会收到SIGABRT消息。 [self.navigationController setToolb
我无法理解以下崩溃,因为它是随机发生的,并且我怀疑可能是多线程问题,但是这里是: Incident Identifier: 0BE956AB-228A-4B1B-8A3D-A99A481F7F3F C
我最近设置了 Crashlytics 以从我的 iOS 应用程序接收崩溃日志,并且我不断收到 SIGABRT 崩溃日志,但我找不到它的来源。 如果你能帮我一点,这是崩溃日志: Exception Ty
我正在尝试通过指针来理解这项工作。所以我编写了一个测试程序,其中通过删除分隔点将名称分成标签。每个标签都表示为长度/数据对,如下所示:google.ru 表示为“x\06googlex\02ru”当我
我正在研究教授给我们的一些旧课本,为即将到来的考试做准备,我遇到了这个问题。 我的任务是从结构如下的文本文件中读取信息: [十进制数字],[罗马数字(字符串)],[o 或 u(优化或未优化的罗马数字)
#toggle the string #include int main() { char S[100],ch; int i=0; gets(S); while((S[i]!
我正在开展一个学校项目,我需要从文件中获取矩阵的信息(高度、宽度、单元格状态)。像这样的事情: 30 40 /*height and width*/ 3 /*nr of lines
我学习 Swift 一段时间了,SIGABRT 信号随机出现了好几次。我尝试过一些在线教程,但似乎并不总是有效。 这次我试图用两个 View Controller 设置一个待办事项列表。一个有一个表格
我在我的项目中添加了第二个目标,以便能够对多个应用程序使用相同的 Xcode 项目(基本应用程序的风格略有变化)。我重命名了目标,更改了方案以匹配名称,还重命名了第二个 info.plist。现在,当
我试图运行一个简单的代码,它编译但当我尝试运行它时我得到(核心转储)错误。于是用gdb查看错误是什么。 代码: #include #include #include void gerar() {
我为这个问题苦苦挣扎了 2 天。我有一个解决方法,但我想了解更多会发生什么。让我们开始吧。我有一个非常原始的异常类,它保存一条错误消息作为指向字符数组的指针(我知道 std::string 的利润)。
NSString *aName = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 1)];
我正在尝试从框架动态加载类,但应用程序因转换发送 SIGABRT 信号而崩溃: let newClassType = NSClassFromString("MyFramework.CustomClas
当我运行我的应用程序时, View Controller 中会调用一个函数,当发生这种情况时,我会收到信号 SIGABRT。 如何解决这个问题? 功能: func setRootViewControl
我正在尝试保存 UISwitch 结果并使用它们来填充 Parse.com 推送通知的“ channel ”。我遵循了解析指南,但每次我尝试单击保存开关值的保存按钮时,我都会收到一个 SIGABRT。
我是一名优秀的程序员,十分优秀!