sscanf对大数字的分段错误

时间:2017-08-16 20:40:04

标签: c file scanf

我在C中相当新,我试图逐行读取一个大文件(> 30米行),并将每行的一些值存储到一个数组中。输入文件的格式为:

1. inode    100660 uid  66322 gid  66068 bytes       5848 blks        128
2. inode    100662 uid  66492 gid  66076 bytes        159 blks          0
3. inode    100647 uid  66419 gid  66068 bytes        235 blks          0
4. inode 100663302 uid  66199 gid  66068 bytes        131 blks          0
5. inode 100663311 uid  66199 gid  66068 bytes        134 blks          0

这是我的代码:

void loadArrayFromFile(char * filename) {
long bytesArray[380000000];
FILE * myfile;
myfile = fopen(filename, "r");
char line[1024];
char inodeText[10];
long int inode = 0;
int mybytes = 0;

if(myfile == NULL) {
    printf("No file found \n");
    exit(EXIT_FAILURE);
}

while(fgets(line, sizeof(line), myfile)) {
    int x = (sscanf(line, "%s %ld %*s %*d %*s %*d %*[bytes] %d %*[^\n]", inodeText, &inode, &mybytes));
    if(x > 1) {
        bytesArray[inode] = mybytes;
    }
}

代码适用于前3行,但是当它到达第4行时,我收到分段错误(核心转储)错误。我怀疑它与inode值太大而无法存储到int中有关,即使int可以存储的最大值是2147483647.任何人都可以帮我解决问题是什么?

1 个答案:

答案 0 :(得分:2)

您使用inode编号作为索引bytesArray。你没有显示这个数组有多大,但我认为它比100663302小得多。所以你要写的是数组的末尾。这会调用undefined behavior

不是使用inode编号作为索引,而是使用包含inode编号和文件大小的struct,并使用这些数组以及数组中元素的计数。

struct entry {
    int inode;
    int nbytes;
};

struct entry entryArray[10];   // assuming there are no more than 10 lines in the file
int arrayLen = 0;

...

while(fgets(line, sizeof(line), myfile)) {
    int x = (sscanf(line, "%s %ld %*s %*d %*s %*d %*[bytes] %d %*[^\n]", inodeText, &inode, &mybytes));
    if(x > 1) {
        entryArray[arrayLen].inode = inode;
        entryArray[arrayLen].nbytes = mybytes;
        arrayLen++;
    }
}