首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >fclose()崩溃c程序

fclose()崩溃c程序
EN

Stack Overflow用户
提问于 2017-02-19 16:36:13
回答 2查看 2K关注 0票数 2

我有一个相对简单的程序,在读取文件中的整数后一直崩溃。它在执行fclose行时崩溃。我已经定位了这个函数中的错误。

代码语言:javascript
复制
// Read array from text file
int * fileRead() {
    FILE *file;
    file = fopen("test.txt", "r");

    // Check if the file exists
    if(file == NULL){
        printf("There was a problem opening the file");
        exit(1);
    }

    // Count number of lines in file
    int count = 0;
    char c;
    for (c = getc(file); c != EOF; c = getc(file)){
        if (c == '\n') { 
            count = count + 1;
        }
    }

    // Reset to top of file
    int t = fseek(file, 0, SEEK_SET);

    // Read each line and save it to temp
    int *temp = malloc(sizeof(int)*count);
    int num, i;
    for (i = 0; i<=count; i++){
        fscanf(file, "%d\n", &temp[i]);
        printf("%d\n", temp[i]);
    }

    fclose(file);
    printf("Hello World\n");
    return temp;
}

“哈罗世界”是为了向我自己证明它完全崩溃了。函数从一个只包含单独行(数量未知)的int的文件中读取ints,并将它们保存到一个数组中,然后返回该数组。谢谢您的帮助,这是我第一次使用c,所以我不知道从哪里开始寻找bug。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-02-19 17:14:53

备注:

C中的索引从0开始。因此,如果您想保存count整数,就必须迭代到count-1

i.e.

  • i < count
  • i <= count-1

你的读数是错误的,因为你假设你的整数是一个数字。

代码语言:javascript
复制
#include<stdio.h>
#include<stdlib.h>

int * fileRead() {
    FILE *file;
    file = fopen("PATH.txt", "r");

    // Check if the file exists
    if(file == NULL){
        printf("There was a problem opening the file");
        exit(1);
    }

    // Count number of lines in file
    int count = 0;
    char pc = '\n';
    char c;
    while (c = fgetc(file), c != EOF)
    {
        if (c == '\n'  &&  pc != '\n')
            count++;
        pc = c;
    }

      // Reset to top of file
    fseek(file, 0, SEEK_SET);

    // Read each line and save it to temp
    int *temp = malloc(sizeof(int)*count);
    int num, i;

    for (i=0; i<count; i++)
    {
        fscanf (file, "%d", &temp[i]);
    }

    fclose(file);
    return temp;
}


int main()
{
    int *t = fileRead();
    printf("%d\n", t[0]);
    printf("%d\n", t[1]);
}

文件:

代码语言:javascript
复制
452
55

输出:

代码语言:javascript
复制
542
55

来总结它:

破坏了我的程序。

不是的。这不是fclose,而是您试图访问未分配的内存。

票数 1
EN

Stack Overflow用户

发布于 2017-02-19 17:54:38

代码中存在多个问题:

  • fgetc(fp)返回一个int值,该值可以具有unsigned char类型的所有值和特殊值EOF。您必须将其存储到int类型的变量中,以便在文件测试结束时可靠。
  • 在循环for (i = 0; i<=count; i++){中,由于分配给块的最大允许索引是count-1,所以会导致缓冲区溢出。这肯定会导致未定义的行为,并很好地解释观察到的行为。 用这个代替: for (i = 0;i< count;i++)
  • 必须将分配的数组的长度传递给调用方。
  • 计算行数并不能准确地确定文件中的条目数。最好是两次解析文件,或者只解析一次,然后动态地重新分配数组。后一种方法对于不可见的输入流(如终端和管道)是必要的。

下面是您的代码的修改版本:

代码语言:javascript
复制
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int *fileRead(int *countp) {

    // Check if the file exists
    FILE *file = fopen("PATH.txt", "r");
    if (file == NULL) {
        fprintf(stderr, "Cannot open input file PATH.txt: %s\n",
                strerror(errno));
        exit(1);
    }

    // Count number of lines in file
    int num, count = 0;
    while (fscanf(file, "%d", &num) == 1) {
        count++;
    }

    // Reset to top of file
    fseek(file, 0, SEEK_SET);

    // Read each line and save it to temp
    int *temp = calloc(sizeof(int), count);
    if (temp != NULL) {
        int i;    
        for (i = 0; i < count; i++) {
            if (fscanf(file, "%d", &temp[i]) != 1) {
                fprintf(stderr, "error reading element number %d\n", i);
                break;
            }
        }
        *countp = i;  // number of entries successfully converted
    }
    fclose(file);
    return temp;
}

int main(void) {
    int count;
    int *t = fileRead(&count);
    if (t != NULL) {
        for (int i = 0; i < count; i++) {
            printf("%d\n", t[i]);
        }
        free(t);
    }
    return 0;
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42329852

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档