I'm trying to write a function that will read and print the contents of a file. I gave the filename as a parameter for my function. I used FILE *testfile
to create a file handle and then I use fread
to read the file. block_t
is a struct and nreserved
are the reserved segments of the block. Each block has records. I don't think that it is necessary to tell you how block_t
is created.
我正在尝试编写一个能够读取和打印文件内容的函数。我把文件名作为我的函数的参数。我使用FILE * testfile创建文件句柄然后使用fread来读取文件。 block_t是一个struct,nreserved是块的保留段。每个块都有记录。我认为没有必要告诉你block_t是如何创建的。
My problem is that even though the function runs and I can see in the console the results that I want to see the process terminates. This happens even if I comment out the if else parts. I get this message Process terminated with status -1073741510
我的问题是,即使该函数运行,我可以在控制台中看到我想看到该过程终止的结果。即使我注释掉了if else部分,也会发生这种情况。我收到此消息流程终止,状态为-1073741510
Here is my code:
这是我的代码:
#include "dbtproj.h"
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <iostream>
using namespace std;
void showEntriesOfBlock(char *filename){
FILE *testfile;
block_t block;
int nreserved;
//open file and print contents
testfile = fopen(filename,"r");
if(testfile==NULL)
cout << "Error";
else{
while(!feof(testfile)){
fread(&block, 1, sizeof(block_t), testfile);
nreserved = block.nreserved;
//print block contents
for (int i=0; i<nreserved; ++i) {
printf("this is block id: %d, record id: %d, num: %d, str: %s\n",
block.blockid, block.entries[i].recid, block.entries[i].num,
block.entries[i].str);
}
}
}
fclose(testfile);
};
In my main file I create a file by using outfile = fopen("file.bin", "w");
then I write random data to the file. Then I close the file with fclose(outfile);
and in the next line I call my function like this showEntriesOfBlock("file.bin");
在我的主文件中,我使用outfile = fopen(“file.bin”,“w”)创建一个文件;然后我将随机数据写入文件。然后我用fclose(outfile)关闭文件;在下一行我调用我的函数就像这个showEntriesOfBlock(“file.bin”);
Can anybody help? I think that I might have messed up my pointers of did something wrong with the file handlers.
有人可以帮忙吗?我想我可能搞砸了我对文件处理程序做错了什么的指示。
This is how I give data to my blocks and records.
这就是我向块和记录提供数据的方式。
for (int b=0; b<nblocks; ++b) { // for each block
block.blockid = b;
for (int r=0; r<MAX_RECORDS_PER_BLOCK; ++r) { // for each record
// prepare a record
record.recid = recid++;
record.num = rand() % 1000;
strcpy(record.str,"hello"); // put the same string to all records
record.valid = true;
memcpy(&block.entries[r], &record, sizeof(record_t)); // copy record to block
}
block.nreserved = MAX_RECORDS_PER_BLOCK;
block.valid = true;
fwrite(&block, 1, sizeof(block_t), outfile); // write the block to the file
}
fclose(outfile);
And here are the definitions of my structs:
以下是我的结构的定义:
// This is the definition of a record of the input file. Contains three fields, recid, num and str
typedef struct {
unsigned int recid;
unsigned int num;
char str[STR_LENGTH];
bool valid; // if set, then this record is valid
} record_t;
// This is the definition of a block, which contains a number of fixed-sized records
typedef struct {
unsigned int blockid;
unsigned int nreserved; // how many reserved entries
record_t entries[MAX_RECORDS_PER_BLOCK]; // array of records
bool valid; // if set, then this block is valid
unsigned char misc;
unsigned int next_blockid;
unsigned int dummy;
} block_t;
2 个解决方案
#1
1
Here's a working version using FILE* (which I wouldn't recommend if you're learning...)
这是使用FILE *的工作版本(如果你正在学习,我不推荐......)
NOTE: open your files in binary mode : fopen(filename, "wb") or fopen(filename, "rb")
注意:以二进制模式打开文件:fopen(filename,“wb”)或fopen(filename,“rb”)
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <iostream>
#include <cassert>
#include <fstream>
const int STR_LENGTH = 10;
const int MAX_RECORDS_PER_BLOCK = 5;
//! For my test I assumed the following definitions.
//! (i.e. that block_t is a POD.)
// This is the definition of a record of the input file. Contains three fields, recid, num and str
typedef struct
{
unsigned int recid;
unsigned int num;
char str[STR_LENGTH];
bool valid; // if set, then this record is valid
} record_t;
// This is the definition of a block, which contains a number of fixed-sized records
typedef struct
{
unsigned int blockid;
unsigned int nreserved; // how many reserved entries
record_t entries[MAX_RECORDS_PER_BLOCK]; // array of records
bool valid; // if set, then this block is valid
unsigned char misc;
unsigned int next_blockid;
unsigned int dummy;
} block_t;
void showEntriesOfBlock(const char *filename)
{
FILE* testfile = fopen(filename, "rb");
assert(testfile);
if (!testfile)
{
perror("Error");
return;
}
block_t block;
while(fread(reinterpret_cast<char*>(&block), sizeof(block_t), 1, testfile))
{
if (ferror(testfile))
{
perror("Error while reading");
return;
}
//print block contents
for (int i = 0; i < block.nreserved; ++i)
{
printf("this is block id: %d, record id: %d, num: %d, str: %s\n",
block.blockid, block.entries[i].recid, block.entries[i].num,
block.entries[i].str);
}
}
fclose(testfile);
};
int main(int argc, const char *argv[])
{
std::string filename = "g:/test.dat";
FILE* outfile;
outfile = fopen(filename.c_str(), "wb");
int nblocks = 10;
int recid = 0;
for (int b = 0; b < nblocks; ++b)
{
block_t block;
block.blockid = b;
for (int r = 0; r < MAX_RECORDS_PER_BLOCK; ++r)
{
// for each record
// prepare a record
record_t record;
record.recid = recid++;
record.num = rand() % 1000;
strcpy(record.str, "hello"); // put the same string to all records
record.valid = true;
memcpy(&block.entries[r], &record, sizeof(record_t)); // copy record to block
}
block.nreserved = MAX_RECORDS_PER_BLOCK;
block.valid = true;
fwrite(&block, sizeof(block_t), 1, outfile); // write the block to the file
}
fclose(outfile);
showEntriesOfBlock(filename.c_str());
return 0;
}
#2
0
Try this:
尝试这个:
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <iostream>
#include <cassert>
#include <fstream>
#include <type_traits>
void showEntriesOfBlock(char *filename)
{
std::ifstream testfile(filename, std::ios_base::binary);
assert(testfile);
if (!testfile)
{
std::cout << "Error";
return;
}
block_t block;
int nreserved;
while (testfile)
{
//! This assumes block is a POD.
static_assert(std::is_pod<block_t>::value, "block_t is not a POD.");
testfile.read(reinterpret_cast<char*>(&block), sizeof(block_t));
nreserved = block.nreserved;
//print block contents
for (int i = 0; i < nreserved; ++i)
{
printf("this is block id: %d, record id: %d, num: %d, str: %s\n",
block.blockid, block.entries[i].recid, block.entries[i].num,
block.entries[i].str);
}
}
testfile.close();
};
#1
1
Here's a working version using FILE* (which I wouldn't recommend if you're learning...)
这是使用FILE *的工作版本(如果你正在学习,我不推荐......)
NOTE: open your files in binary mode : fopen(filename, "wb") or fopen(filename, "rb")
注意:以二进制模式打开文件:fopen(filename,“wb”)或fopen(filename,“rb”)
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <iostream>
#include <cassert>
#include <fstream>
const int STR_LENGTH = 10;
const int MAX_RECORDS_PER_BLOCK = 5;
//! For my test I assumed the following definitions.
//! (i.e. that block_t is a POD.)
// This is the definition of a record of the input file. Contains three fields, recid, num and str
typedef struct
{
unsigned int recid;
unsigned int num;
char str[STR_LENGTH];
bool valid; // if set, then this record is valid
} record_t;
// This is the definition of a block, which contains a number of fixed-sized records
typedef struct
{
unsigned int blockid;
unsigned int nreserved; // how many reserved entries
record_t entries[MAX_RECORDS_PER_BLOCK]; // array of records
bool valid; // if set, then this block is valid
unsigned char misc;
unsigned int next_blockid;
unsigned int dummy;
} block_t;
void showEntriesOfBlock(const char *filename)
{
FILE* testfile = fopen(filename, "rb");
assert(testfile);
if (!testfile)
{
perror("Error");
return;
}
block_t block;
while(fread(reinterpret_cast<char*>(&block), sizeof(block_t), 1, testfile))
{
if (ferror(testfile))
{
perror("Error while reading");
return;
}
//print block contents
for (int i = 0; i < block.nreserved; ++i)
{
printf("this is block id: %d, record id: %d, num: %d, str: %s\n",
block.blockid, block.entries[i].recid, block.entries[i].num,
block.entries[i].str);
}
}
fclose(testfile);
};
int main(int argc, const char *argv[])
{
std::string filename = "g:/test.dat";
FILE* outfile;
outfile = fopen(filename.c_str(), "wb");
int nblocks = 10;
int recid = 0;
for (int b = 0; b < nblocks; ++b)
{
block_t block;
block.blockid = b;
for (int r = 0; r < MAX_RECORDS_PER_BLOCK; ++r)
{
// for each record
// prepare a record
record_t record;
record.recid = recid++;
record.num = rand() % 1000;
strcpy(record.str, "hello"); // put the same string to all records
record.valid = true;
memcpy(&block.entries[r], &record, sizeof(record_t)); // copy record to block
}
block.nreserved = MAX_RECORDS_PER_BLOCK;
block.valid = true;
fwrite(&block, sizeof(block_t), 1, outfile); // write the block to the file
}
fclose(outfile);
showEntriesOfBlock(filename.c_str());
return 0;
}
#2
0
Try this:
尝试这个:
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <iostream>
#include <cassert>
#include <fstream>
#include <type_traits>
void showEntriesOfBlock(char *filename)
{
std::ifstream testfile(filename, std::ios_base::binary);
assert(testfile);
if (!testfile)
{
std::cout << "Error";
return;
}
block_t block;
int nreserved;
while (testfile)
{
//! This assumes block is a POD.
static_assert(std::is_pod<block_t>::value, "block_t is not a POD.");
testfile.read(reinterpret_cast<char*>(&block), sizeof(block_t));
nreserved = block.nreserved;
//print block contents
for (int i = 0; i < nreserved; ++i)
{
printf("this is block id: %d, record id: %d, num: %d, str: %s\n",
block.blockid, block.entries[i].recid, block.entries[i].num,
block.entries[i].str);
}
}
testfile.close();
};