用Fgets读取行(?)和一点C ++ {新手程序员} [英] Reading Lines with Fgets(?) and a bit of C++ {Novice Programmer}

查看:58
本文介绍了用Fgets读取行(?)和一点C ++ {新手程序员}的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您好。

我有一个文件(用于学校作业),格式如下,并且

分隔符格式。文件中的每条记录都具有以下格式:

123423454567987,29873,James,Ha * rry,St。路易斯,416-555-5555;

" accountNumber,balance,lastNam * e,city,phoneNumber; "每条记录都是

保证不超过350个字符。 "平衡"不再是
而不是20个字符,accountNumber正好是15个字符和

lastName,firstName,city,phone * Number中的字符总数;



不超过315个字符。使用复制(初始化)的所有规则,将此记录中的字段复制到数组中第一个空帐户的

相应数据成员

Saving。

a3.dat的内容

123423454567987,29873,James,Ha * rry,St。

Louis,416-555-5555; 22342345456 * 7987, 198745,Jones,Beth,Toronto *,4 16-555-5556; 323423454567987,* 2349,Ng,Wei,Montreal,416-555-5 * 557; 423423454567987,9234617,Wo * o,Charles,Winnipe g,416- 555-555 * 8; 523423454567987,2534,DeJesus *,Pancho,Edmonto n,416-555-5559; * 623423454567987,543876,Smith,B * ob,Charlottet拥有,416-555-5544; * 723423454567987,1234,Kasim ,Vla * dislov,Halifa x,416-555-5566; 82 * 3423454567987,98765,Yamaha,Dav * id,Vancouve r,416-555-5577; 9234 * 23454567987,26486,Lee,Jim,Calg * ary,416 -555-5588; 1134234545679 * 87,83456,Baker,Susan,St。


Louis-de-ha-ha,416-555-5599; 13 * 3423454567987,29873,James ,Harr * y,St。

Louis,416-555-5555;

由于每个记录都是不是一行,并且在

文件中显示为(上图),我怎么去读取每个记录,提取信息

并发送它到

数组中第一个空对象的正确数据成员?


到目前为止,我有这样的功能


void Bank :: workFP(FILE * fp)

{

if(fp!= NULL){


}

else printf(无法打开文件。\ n);

}

提前致谢。感谢任何帮助。

解决方案

它不是不错。因为数据文件故意混淆。一个

的方法是准确读取350个字符,并根据您为数据元素列出的规则解析

。然后,

保存剩余部分。再次循环,并读取另一个350,前置

余数并继续。请记住,你不会有漂亮的NULL

终止字符串,并检查你是否读过350个字符。


AMT2K5写道:



因为每个记录都是不是一行,并在
文件中显示为(上图),我怎么去阅读每个记录




从你的描述:每个记录以'';''字符结尾。

因此逐个字符阅读,直到遇到'';''。将这些

字符保存在缓冲区中(可能是std :: string)。然后你有一个记录的所有

字符,可以继续将它分成

个别作品。


-

Karl Heinz Buchegger
kb******@gascad.at


因为你不能保证每条记录占据它自己的行,那么你需要将整个文件读入内存。如果你可以保证文件的大小不是很大,那么你可以将while

文件读入char *缓冲区或std :: string对象:


if(fp!= NULL)

{

char * chunk = new char [256];

std :: string sBuffer;

while(!feof(fp))

{

fread(chunk,sizeof( char),256,fp); //你甚至可以将

读入字符串结构中,但我不确定

string = string + sBuffer;

}

delete [] chunk;

chunk = null;

DoParsingAndOtherStuff(string);

}


一旦你将整个文件放在缓冲区中,就可以很容易地使用字符串

操作来解析它,首先是'';''获取记录,然后按'','

来获取每条记录中的字段。


如果你不能保证该文件是合理的,然后它b / b $ b $变得更加棘手。你必须首先分析每个块的记录,然后

然后做一个fseek到达你离开的文件中的最后一个位置:


if( fp!= NULL)

{

char * chunk = new char [256];

int nextstartposition = 0;

while(!feof(fp))

{

fseek(fp,nextstartposition,0);

fread(chunk,sizeof (char),256,fp);

nextstartposition = nextstartposition +

DoParsingAndOtherStuff(块)

}

删除[] chunk;

chunk = null;

}


在这种情况下,DoParsingAndOtherStuff做同样的事情,但它有返回

返回最后一个'';''的位置,因为之后的所有内容都只是部分记录。然后该文件可以寻找新的起始位置,并读取另一个块。真的只有一点点,比把整个东西都读到记忆中要难得多了。

如果你需要DoParsingAndOtherStuff的帮助,那么
,让

我知道。


希望这会有所帮助,


jason


Hello.
I have a file (for a school assignment) with the following format and
delimiter format. Each record in the file has the following format:
123423454567987,29873,James,Ha*rry,St. Louis,416-555-5555;
"accountNumber,balance,lastNam*e,city,phoneNumber; " Each record is
guranteed to be no longer than 350 characters. "balance" is no longer
than 20 characters, "accountNumber" is exactly 15 characters and the
total number of characters in "lastName,firstName,city,phone*Number;"
is
no longer than 315 characters. Copy the fields in this record to the
appropriate data member of the first empty Account in the array
savings, using all the rules for copying (initializing).
Contents of a3.dat
123423454567987,29873,James,Ha*rry,St.
Louis,416-555-5555;22342345456*7987,198745,Jones,Beth,Toronto*,4 16-555-5556;323423454567987,*2349,Ng,Wei,Montreal,416-555-5*557;423423454567987,9234617,Wo*o,Charles,Winnipe g,416-555-555*8;523423454567987,2534,DeJesus*,Pancho,Edmonto n,416-555-5559;*623423454567987,543876,Smith,B*ob,Charlottet own,416-555-5544;*723423454567987,1234,Kasim,Vla*dislov,Halifa x,416-555-5566;82*3423454567987,98765,Yamaha,Dav*id,Vancouve r,416-555-5577;9234*23454567987,26486,Lee,Jim,Calg*ary,416-555-5588;1134234545679*87,83456,Baker,Susan,St.

Louis-de-ha-ha,416-555-5599;13*3423454567987,29873,James,Harr*y,St.
Louis,416-555-5555;
Since each "record" is not a line and is shown as is (above) in the
file, how might I go and read each "record", extract the information
and send it to the correct data member of the first empty object in the
array?

So far I have my function like this

void Bank::workFP(FILE* fp)
{
if(fp != NULL){

}
else printf("Unable to open file.\n");
}
Thanks in advance. Appreciate any help whatsoever.

解决方案

It''s not "nice" because the data file is intentionally jumbled. One
way to do this is to read exactly 350 characters, and parse it
according to the rules you''ve outlined for the data elements. Then,
save-off the remainder. Loop again, and read another 350, prepend the
remainder and continue. Keep in mind that you will not have nice NULL
terminated strings, and also check that you read 350 characters.


AMT2K5 wrote:



Since each "record" is not a line and is shown as is (above) in the
file, how might I go and read each "record"



From your description: Each "record" ends with a '';'' character.
So read character by character until you encounter a '';''. Save those
characters in a buffer (probably a std::string). Then you have all
characters for one record and can proceed to break it into
individual pieces.

--
Karl Heinz Buchegger
kb******@gascad.at


since you can''t guarantee that each record occupies it''s own line, then
you will have to read the whole file into memory. if you can gaurantee
that the file is not of huge size, then you can just read the while
file into a char* buffer, or a std::string object:

if (fp != NULL)
{
char *chunk = new char[256];
std::string sBuffer;
while (!feof(fp))
{
fread(chunk, sizeof(char), 256, fp); // you might even be able to
read right into the string struct, but i''m not sure
string = string + sBuffer;
}
delete[] chunk;
chunk = null;
DoParsingAndOtherStuff(string);
}

once you have the whole file in a buffer, it''s easy to use string
manipulation to parse it, first by '';'' to get the records, then by '',''
to get the fields in each record.

if you can''t gaurantee that the file is reasonable in size, then it
gets trickier. you have to analyze each chunk for records first, and
then do an fseek to get to the last place in the file you left off:

if (fp != NULL)
{
char *chunk = new char[256];
int nextstartposition = 0;
while (!feof(fp))
{
fseek(fp, nextstartposition, 0);
fread(chunk, sizeof(char), 256, fp);
nextstartposition = nextstartposition +
DoParsingAndOtherStuff(chunk)
}
delete[] chunk;
chunk = null;
}

in this case DoParsingAndOtherStuff does the same thing, but it has to
return the position that the last '';'' was found on, because everything
after that was only a partial record. then the file can seek to that
new starting location, and read another chunk. it''s only a little
trickier than reading the whole thing into memory, really.

if you need help with what DoParsingAndOtherStuff would look like, let
me know.

hope this helps,

jason


这篇关于用Fgets读取行(?)和一点C ++ {新手程序员}的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆