C简单代码,带填充数组

时间:2017-04-07 03:34:42

标签: c arrays scanf

我尝试使用名为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]);
}

2 个答案:

答案 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-prototypesmain()函数告诉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个值更令人兴奋的事情。我可能会将文件读取代码放在与文件打开/关闭代码不同的函数中。