因此,对于我的学校课程,我只需要从以下格式的文本文件中读取整数列表,第一行表示整数的数量。然后对整数进行排序(它们在 txt 文件中未排序),然后找到平均值。我只是试图从我一直使用的测试文件中将整数读入数组.txt。
9
1
3
阿拉伯数字
四
。
#include<stdio.h>
#include<stdlib.h>
int amtValues;
int *values;
float find_median (int* values){
if(amtValues%2==0){
return ((values[amtValues/2] + values[amtValues/2 -1]) /2.0);
}
else
return values[amtValues/2];
}
int main(int argc, char **argv){
//open the file, copy the data from the file, and determine the number of values
//open the filestream
FILE* fp = fopen(argv[1], "r");
if(!fp){
printf("error reading filen");
return 1;
}
//determine the number of values
char *lineOne;
if(fgets(lineOne, 80, fp)!=1)
puts (lineOne);
lineOne++;
amtValues = atoi(lineOne);
printf("nThe amount of values is: %dn",amtValues);
/*allocate memory for values array, and copy the values from file.*/
values = (int*)malloc(amtValues*sizeof(int));
int i=0;
while(!feof(fp)){
int curNum;
fscanf(fp, "%d", &curNum);
values[i] = curNum;
i++;
}
fclose(fp);
for(i=0; i<amtValues; i++)
printf("n%d");
}
这就是我目前要做的事情,我收到一个错误,说分段错误(核心转储)。我是C的新手,所以我真的不确定这意味着什么。
我没有检查您的整个代码,但这里会导致分段错误:
//determine the number of values
char *lineOne;
if(fgets(lineOne, 80, fp)!=1)
puts (lineOne);
你需要有内存来lineOne
.只有指针并不意味着你有缓冲区的内存,你需要在堆或堆栈上分配它。像这样尝试:
char lineOne[81]; // allocation on stack
或
char *lineOne = malloc(sizeof(*lineone) * 81); // allocate on heap
我收到一个错误说:分段错误(核心转储)
分段错误实际上是一些未定义的行为(UB),这意味着您的程序有问题,因为计算机正在取消引用一些无效的内存地址(在进程的虚拟地址空间之外)。
(我猜你在Linux或其他POSIX系统上,但这应该在你的问题中提到)
核心转储(在 Linux 上,有关详细信息,请参见 core(5))是一个文件(通常命名为core
- 描述错误进程的状态(当故障发生时,参见 signal(7)),特别是它的虚拟地址空间。可以使用gdb
调试器在事后调试核心转储。你也可以禁用核心转储(但你最好不要,它们非常有用),例如,内置ulimit -c
bash(或setrlimit(2)系统调用)。
但是,并非所有未定义的行为都会给出这样的错误。你很幸运能得到一个。并且可能会发生(例如,由于 ASLR)再次运行相同的错误可执行文件不会核心转储或段错误(但会有一些更糟糕的行为)。
在实践中:
-
使用所有警告和调试信息进行编译:使用 GCC
gcc -Wall -Wextra -g
。改进您的代码以完全不收到警告(在您的情况下,您的代码会收到一些警告)。 -
阅读文档,特别是编译器的文档,以及您正在使用的每个函数(例如,您错误地使用了
fgets
:它永远不会给出 1)。后来,您甚至可以阅读 C11 标准 n1570。 -
了解如何使用
gdb
调试器来了解错误程序的行为。这是一项需要掌握的基本技能。你应该进行测试。 -
了解更多关于UB的信息,并非常害怕它们。最糟糕的 UB 是显然不会(总是)出错的 UB 。像valgrind这样的工具很有帮助。
也许你想使用 getline(3)。看到这里。也许你可以有一个灵活的数组成员,就像这里一样,用一些抽象数据类型来推理。
还要注意停止问题及其不可判定性。
所有开发人员都会犯错误。找到它们具有挑战性,也可能很有趣。但是编程是困难的。