我尝试使用名为data.txt
的文件填充数组。我不知道代码有什么问题。我得到分段错误:11错误。
#include <stdio.h>
#include <stdlib.h>
void input(int arr[]){
FILE* f;
int x, i=0;
f= fopen("data.txt","r");
while (arr[i] != EOF){
fscanf(f,"%d",&x);
arr[i] = x;
i++;
}
fclose(f);
}
int main(){
int arr[50];
input(&arr[50]);
printf("%d", arr[0]);
}
答案 0 :(得分:2)
您正在将该号码读入x
(您要复制到arr[i]
),然后将arr[i+1]
与EOF
进行比较。这不是必须如何完成的。
试试这个
while (fscanf(f, "%d", &arr[i]) == 1)
i++;
但这会违反如此多的安全限制。如果i
大于某个限制,则更好地限制检查和中断,但应将该限制传递给函数。
另一个错误是如何将参数传递给输入。通过input(arr)
代替input(&arr[50])
。如果您想使用&
,请使用input(&arr[0])
。
答案 1 :(得分:0)
这将更接近我的代码版本:
#include <stdio.h>
#include <stdlib.h>
static int input(int size, int arr[])
{
const char file[] = "data.txt";
FILE *f = fopen(file, "r");
if (f == NULL)
{
fprintf(stderr, "Failed to open file '%s' for reading\n", file);
exit(EXIT_FAILURE);
}
int i;
for (i = 0; i < size && fscanf(f, "%d", &arr[i]) == 1; i++)
;
fclose(f);
return i;
}
int main(void)
{
int arr[50];
int num = input(50, arr);
for (int i = 0; i < num; i++)
printf("%d: %d\n", i, arr[i]);
return 0;
}
在函数之前使用static
来平息-Wmissing-prototypes
。 main()
函数告诉input()
函数数组中有多少元素,因此input()
函数可以避免溢出缓冲区(堆栈溢出,不能少)。 input()
函数告诉main()
函数它读取了多少个值,因此main()
函数不会访问未初始化的数据。关键函数调用已经过错误检查 - fopen()
和fscanf()
。
代码使用GCC 6.3.0和下面的命令行(源文件为rf19.c
)在运行macOS Sierra 10.12.4的Mac上干净地编译:
$ gcc -O3 -g -std=c11 -Wall -Wextra -Werror -Wmissing-prototypes \
> -Wstrict-prototypes -Wold-style-definition rf19.c -o rf19
$
我生成了一个包含23个随机整数的数据文件,其中10到99之间,输出为:
$ ./rf19
0: 48
1: 33
2: 77
3: 42
4: 78
5: 51
6: 85
7: 56
8: 55
9: 56
10: 16
11: 38
12: 39
13: 52
14: 34
15: 63
16: 20
17: 23
18: 23
19: 19
20: 39
21: 44
22: 71
$
这不是非常有用的信息,但总比没有好。
代码仍有缺陷,我不打算修复 - 有些比其他更严重。例如,文件名是固定的 - 这是禁忌。 input()
函数中的代码出错;这不一定好。它会产生标准错误的错误消息 - 比标准输出更好,但在GUI应用程序中不是一个好主意。输出浪费了大量的水平空间;显示的数据,你可以得到每个输出行10个值(每行约70个字符),但打印更复杂,所以我没有显示它。该代码将EOF和数据中的单词或标点符号视为相同;可能会或可能不重要,具体取决于您的申请。输入在第50次输入后停止;也许你需要知道是否有更多的条目可供阅读。我可能会将命令行参数作为文件名处理,或者如果没有指定文件则处理标准输入 - Unix&#39; filter命令&#39;成语。我可能会做一些比打印前50个值更令人兴奋的事情。我可能会将文件读取代码放在与文件打开/关闭代码不同的函数中。