将数据从文件读入2个数组

时间:2011-06-10 21:19:09

标签: c ubuntu

我试图从文件中读取数据,文件设置如下:

3050 76
2030 60
1600 70
2222 50
2430 60
2800 50
0 0

第一个数字代表学生ID,第二个数字代表学生的成绩 当程序达到0 0时,它应该停止从文件中读取

这是一个程序示例,它不是从文件中读取的,因为出现了一个名为SEGMENTATION FAULT的错误。我正在使用ubuntu,这是发生此错误

// this is the grading sorting program for part one


#include <stdio.h>
#include <stdlib.h>

#define SIZE 50

int main(int argc, char **argv)
{
    FILE* fp; // file pointer, points to the file
    char file_name[32]; // store file name

    int ID[SIZE];
    int grade[SIZE];

    int a,b; // index variables

    int student_id, grades;

    // opening file by asking the user for the file name
    printf("Enter the name of the file containing the grades\n");
    scanf("%s",file_name);

    fp=fopen("file_name", "r");

    /*fp = fopen("grades.txt", "r");*/

    // read in data into the arrays
    for (a = 0; a <= SIZE; a++)
    {
        fscanf(fp,"%d", &student_id);
        ID[a] = student_id;

        for(b = 0; b <= SIZE; b++)
        {
            fscanf(fp,"%d", &grades);
            grade[b] = grades;
        }

        if(ID[a] == 0 && grade[b] == 0)
            break;
    }

    fclose(fp);
    return 0;
}

8 个答案:

答案 0 :(得分:1)

这听起来像是了解gdb的绝佳机会。由于您使用的是ubuntu,因此默认情况下应该安装它。

使用-gdb3编译您的程序并将其加载到gdb:

gdb -q ./a.out

使用r运行它,gdb将显示segfault发生的位置,使用print语句从那里检查变量。

$ gdb -q a.out 
Reading symbols from /home/user/tmp/SO/bytes/a.out...done.
(gdb) r
Starting program: /home/user/tmp/SO/bytes/a.out 

Program received signal SIGSEGV, Segmentation fault.
0x080483a4 in main () at sf.c:7
7       *p = 2;
(gdb) print p
$1 = (int *) 0x0

答案 1 :(得分:1)

这里有很多东西,例如:

  • 文件名可能不正确 - fopen("file_name",...总是会打开一个名为“filename”的文件

  • 您正在创建长度为50(SIZE)的ID和成绩数组 - 在C中,这意味着数组索引的范围从0到49,但是a和b for循环从0到0 50。

  • 您没有对fscanf的输出进行任何健全性检查,也没有检查您是否可以实际打开该文件。

我建议您阅读C数组,字符串处理和文件I / O操作 - 您可以通过Google找到大量的教程。

答案 2 :(得分:1)

<强>第一 这是不正确的

fp=fopen("file_name", "r");

可能你的意思是

fp=fopen(file_name, "r");

<强>第二 在读取SIZE次数的整数

之前,不要退出此循环
for(b = 0; b < SIZE; b++)
        {
            fscanf(fp,"%d", &grades);
            grade[b] = grades;
        }

你不必为此做一个循环:我想

fscanf(fp,"%d", &grades);
相反,你真的需要阅读成绩。

<强>第三 请记住始终测试fscanf()和fopen()

的返回码

示例:

if ((fp=fopen(file_name,"r"))==NULL) exit(-9);
do {
    if (fscanf(fp,"%d",&(ID[a]))!=1) break;
    if (fscanf(fp,"%d",&(grade[a]))!=1) break; 
}
while((grade[a]!=0) && (ID[a++]!=0));

答案 3 :(得分:0)

提示您正在阅读许多价值观。您有一个嵌套的for循环,它将尝试读取大小*大小实体。

答案 4 :(得分:0)

你的问题可能就是这个部分:

fp=fopen("file_name", "r");

您想要使用变量file_name:

fp=fopen(file_name, "r");

要使程序不易出错,应始终检查文件是否已成功打开:

fp=fopen("file_name", "r");
if (!fp)
  return -1;

答案 5 :(得分:0)

它没有解决问题,但改为(a = 0; a&lt; = SIZE; a ++) 为(a = 0; a&lt; SIZE; a ++)

答案 6 :(得分:0)

您正在打开名为“file_name”的文件,该文件可能不是从命令行扫描的文件。

要解决此问题,请删除行

上的引号
   fp=fopen("file_name", "r");

答案 7 :(得分:0)

你不需要内循环,并且你正在读取类似“〜/ file_name”的东西,这可能不存在所以fp将是NULL(你没有检查)所以任何尝试使用它会导致崩溃。