fclose() 崩溃的 C 程序
fclose() crashing c program
我有一个相对简单的程序,它在从文件中读取整数后一直崩溃。它在执行 fclose 行时崩溃。我已将错误定位到此函数中。
// 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;
}
Hello World 是为了向我自己证明它恰好在 fclose 崩溃。该函数从一个文件中读取整数,该文件仅包含单独行上的整数(数量未知),并将它们保存到一个数组中,然后 returns 该数组。预先感谢您的帮助,这是我第一次使用 c,所以我不确定从哪里开始寻找错误。
备注:
c中的索引从0开始。所以如果你想保存count
个整数,你必须迭代到count-1
。
i.e.
i < count
i <= count-1
你的读数是错误的,因为你假设你的整数是一位数。
#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]);
}
文件:
452
55
输出:
542
55
总结一下:
fclose() crashing my program.
没有。这不是 fclose
,而是您试图访问未分配的内存。
您的代码中存在多个问题:
fgetc(fp)
returns 一个 int
值,可以具有类型 unsigned char
的所有值和特殊值 EOF
。您必须将其存储到 int
类型的变量中,以使文件结束测试可靠。
在循环 for (i = 0; i<=count; i++){
中导致缓冲区溢出,因为分配块的最大允许索引是 count-1
。这肯定会导致未定义的行为,并且可以很好地解释观察到的行为。
改用这个:
for (i = 0; i < count; i++) ...
您必须将分配的数组的长度传回给调用者。
计算行数并不能准确确定文件中的条目数。最好解析文件两次或只解析一次并动态重新分配数组。后一种方法对于不可搜索的输入流(例如终端和管道)是必需的。
这是您的代码的修改版本:
#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;
}
我有一个相对简单的程序,它在从文件中读取整数后一直崩溃。它在执行 fclose 行时崩溃。我已将错误定位到此函数中。
// 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;
}
Hello World 是为了向我自己证明它恰好在 fclose 崩溃。该函数从一个文件中读取整数,该文件仅包含单独行上的整数(数量未知),并将它们保存到一个数组中,然后 returns 该数组。预先感谢您的帮助,这是我第一次使用 c,所以我不确定从哪里开始寻找错误。
备注:
c中的索引从0开始。所以如果你想保存count
个整数,你必须迭代到count-1
。
i.e.
i < count
i <= count-1
你的读数是错误的,因为你假设你的整数是一位数。
#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]);
}
文件:
452
55
输出:
542
55
总结一下:
fclose() crashing my program.
没有。这不是 fclose
,而是您试图访问未分配的内存。
您的代码中存在多个问题:
fgetc(fp)
returns 一个int
值,可以具有类型unsigned char
的所有值和特殊值EOF
。您必须将其存储到int
类型的变量中,以使文件结束测试可靠。在循环
for (i = 0; i<=count; i++){
中导致缓冲区溢出,因为分配块的最大允许索引是count-1
。这肯定会导致未定义的行为,并且可以很好地解释观察到的行为。改用这个:
for (i = 0; i < count; i++) ...
您必须将分配的数组的长度传回给调用者。
计算行数并不能准确确定文件中的条目数。最好解析文件两次或只解析一次并动态重新分配数组。后一种方法对于不可搜索的输入流(例如终端和管道)是必需的。
这是您的代码的修改版本:
#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;
}