读取二进制文件,直到“\ name\”;遇到了...... [英] Read a binary file until "\name\" is encountered...

查看:57
本文介绍了读取二进制文件,直到“\ name\”;遇到了......的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试着写一个应该通过搜索字符序列的二进制文件来读取
的程序\ name \>

然后它应该读取\ name \之后的字符。序列

直到遇到NULL字符。


但是当我的程序运行时它会收到一个SIGSEGV(Segmentation vioalation)信号。

有什么不对?

还有比我更好的方法来解决这个任务(最有可能)


代码:

---------------------------------------------- ------------------

int main()

{

FILE * fp ;

fp = fopen(" demo.dem"," rb");


char cTkn;

char sName [50];

int i = 0,j = 0;

while(!(feof(fp)))

{

if(fread(& cTkn,sizeof(cTkn),1,fp))

{

if(cTkn ==((char )92))//如果找到字符''\''

{

fread(& cTkn,sizeof(cTkn),1,fp);

if(cTkn ==((char)110))//如果找到'n'字符

{

fread (& cTkn,sizeof(cTkn),1,fp);

if(cTkn ==((char)97))// if t他找到了'a''字符

{

fread(& cTkn,sizeof(cTkn),1,fp);

if(cTkn ==((char)109))//如果找到m字符

{

fread(& cTkn,sizeof(cTkn) ),1,fp);

if(cTkn ==((char)101))//如果找到'e'字符

{

fread(& cTkn,sizeof(cTkn),1,fp);

if(cTkn ==((char)92))//如果字符''\\找到了

{

//这里是完整的\ name \已找到字符串

而(cTkn!=((char)0))

{

fread(& sName [j], sizeof(cTkn),1,fp);

j ++;

}

}

}

}

}

}

}

}

i ++;

}

printf(" Read%d characters!\ n",i);

printf(" Found: %s",sName);

fclose(fp);


返回0;

}

------------------------------------------------ ----------------

Im trying to write a program that should
read through a binary file searching for the character sequence "\name\"

Then it should read the characters following the "\name\" sequence
until a NULL character is encountered.

But when my program runs it gets a SIGSEGV (Segmentation vioalation) signal.

Whats wrong?
And is there a better way than mine to solve this task (most likely)

Code:
----------------------------------------------------------------
int main()
{
FILE *fp;
fp = fopen("demo.dem","rb");

char cTkn;
char sName[50];
int i=0,j=0;
while(!(feof(fp)))
{
if(fread(&cTkn, sizeof(cTkn), 1, fp))
{
if(cTkn == ((char)92)) // if the character ''\'' is found
{
fread(&cTkn, sizeof(cTkn), 1, fp);
if(cTkn == ((char)110)) // if the character ''n'' is found
{
fread(&cTkn, sizeof(cTkn), 1, fp);
if(cTkn == ((char)97)) // if the character ''a'' is found
{
fread(&cTkn, sizeof(cTkn), 1, fp);
if(cTkn == ((char)109)) // if the character ''m'' is found
{
fread(&cTkn, sizeof(cTkn), 1, fp);
if(cTkn == ((char)101)) // if the character ''e'' is found
{
fread(&cTkn, sizeof(cTkn), 1, fp);
if(cTkn == ((char)92)) // if the character ''\'' is found
{
// here the complete "\name\" string has been found
while(cTkn != ((char)0))
{
fread(&sName[j], sizeof(cTkn), 1, fp);
j++;
}
}
}
}
}
}
}
}
i++;
}
printf("Read %d characters!\n", i);
printf("Found: %s",sName);
fclose(fp);

return 0;
}
----------------------------------------------------------------

推荐答案

2004年2月25日07:34:40 -0800,< a href =mailto:jo ** @ ljungh.se> jo ** @ ljungh.se (spike)写道:
On 25 Feb 2004 07:34:40 -0800, jo**@ljungh.se (spike) wrote:
我试着写一个程序应该读取二进制文件,搜索字符序列\ name \

然后它应该读取\ name \之后的字符。序列
直到遇到NULL字符。

但是当我的程序运行时,它会收到一个SIGSEGV(Segmentation vioalation)信号。

什么错了?
有没有比我更好的方法来解决这个任务(最有可能)


我是这么认为的。这是我刚刚聚集在一起的版本:

#include< stdio.h>


#define MAX 50


int main()

{

FILE * fp;

char cTkn,c;

char sName [MAX];

int inTxt = 0,pos;

size_t charCount = 0;


const char * txt =" \\\\
ame \\";


fp = fopen(" demo.dem"," rb");


while((cTkn = getc(fp))!= EOF)

{

++ charCount;

if (inTxt == 0)

{

if(cTkn == txt [0])

{

++ inTxt;

}

}

else

{

if( cTkn == txt [inTxt])

{

if(txt [++ inTxt] ==''\ 0'')

休息;

}

其他

inTxt = 0;

}

} $ / $

pos = 0;

while((c = getc(fp))!= EOF&& pos< MAX&& c!=''\ 0'')

{

sName [pos ++] = c;

}

sName [pos] = ''\''';


printf(" Read%d characters!\ n",charCount);

printf(" Found :%s",sName);

fclose(fp);


返回0;

}

你的版本有很多问题...

代码:
----------------------- -----------------------------------------
int main()
{
FILE * fp;
fp = fopen(" demo.dem"," rb");


出于好奇,您真的使用的是C99编译器,还是C ++

编译器?如果你想保持C89的兼容性,把你所有的

声明/之前/你的其他陈述放在一个区块内。

char cTkn;
char sName [50] ;
int i = 0,j = 0;


如果你打算我计算总人数,那就不是......

while(!(feof(fp)))
{
if(fread(& cTkn,sizeof(cTkn),1,fp))


请注意,你没有在任何地方检查EOF除了在你的第一个fread中的

循环的顶部和(有点)。


此外,getc更容易用于读取单个字符而不是你在做什么(虽然我猜你在做什么在技术上并没有错,除了

不检查EOF是坏消息。)

{
if(cTkn ==((char)92))//如果找到字符''\''
{
fread(&) cTkn,sizeof(cTkn),1,fp);
if(cTkn ==((char)110))//如果找到字符n
{
fread (& cTkn,sizeof(cTkn),1,fp);
if(cTkn ==((char)97))//如果字符''a''是发现
{fread(& cTkn,sizeof(cTkn),1,fp);
if(cTkn ==((char)109))//如果字符''m ''被发现
{/ / fTkn,sizeof(cTkn),1,fp);
if(cTkn ==((char)101))//如果角色''e''被发现
{/ / fTkn,sizeof(cTkn),1,fp);
if(cTkn ==((char)92))//如果找到字符''\''
{
//这里完整的\ name \已找到字符串
while(cTkn!=((char)0))


这里你将进入一个无限循环,因为cTkn永远不会改变

基于下面的误差。然而,这不是导致seg错误的恐惧,而是b $ b;它是你在sName缓冲区末尾的递增j然后

有fread尝试写入该位置...(好吧,我想即使只是

地址有未定义的行为,对于纯粹主义者来说)


{
fread(& sName [j],sizeof(cTkn),1,fp);
j ++ ;
}
}
}
}
}
}
}
i ++;
}
printf(" read%d characters!\ n",i);
printf(" Found:%s",sName);
fclose(fp);

返回0;
}
------------------------------- ---------------------------------
Im trying to write a program that should
read through a binary file searching for the character sequence "\name\"

Then it should read the characters following the "\name\" sequence
until a NULL character is encountered.

But when my program runs it gets a SIGSEGV (Segmentation vioalation) signal.

Whats wrong?
And is there a better way than mine to solve this task (most likely)
I think so. Here''s a version I just threw together:
#include <stdio.h>

#define MAX 50

int main()
{
FILE *fp;
char cTkn, c;
char sName[MAX];
int inTxt = 0, pos;
size_t charCount = 0;

const char *txt = "\\name\\";

fp = fopen("demo.dem","rb");

while ((cTkn = getc(fp)) != EOF)
{
++charCount;
if (inTxt == 0)
{
if (cTkn == txt[0])
{
++inTxt;
}
}
else
{
if (cTkn == txt[inTxt])
{
if (txt[++inTxt] == ''\0'')
break;
}
else
inTxt = 0;
}
}

pos = 0;
while ((c = getc(fp)) != EOF && pos < MAX && c != ''\0'')
{
sName[pos++] = c;
}
sName[pos] = ''\0'';

printf("Read %d characters!\n", charCount);
printf("Found: %s",sName);
fclose(fp);

return 0;
}
Your version has a bunch of problems...

Code:
----------------------------------------------------------------
int main()
{
FILE *fp;
fp = fopen("demo.dem","rb");
Just out of curiosity, are you really using a C99 compiler, or a C++
compiler? If you want to maintain C89 compatibility, put all your
declarations /before/ your other statements within a block.

char cTkn;
char sName[50];
int i=0,j=0;
If you''re intending i to count total characters, it isn''t...
while(!(feof(fp)))
{
if(fread(&cTkn, sizeof(cTkn), 1, fp))
Note that you''re not checking for EOF anywhere except at the top of the
loop and (sort of) up in your first fread.

Also, getc is easier to use to read a single character than what you''re
doing (although I guess what you''re doing is not technically wrong, except
that not checking for EOF is bad news.)
{
if(cTkn == ((char)92)) // if the character ''\'' is found
{
fread(&cTkn, sizeof(cTkn), 1, fp);
if(cTkn == ((char)110)) // if the character ''n'' is found
{
fread(&cTkn, sizeof(cTkn), 1, fp);
if(cTkn == ((char)97)) // if the character ''a'' is found
{
fread(&cTkn, sizeof(cTkn), 1, fp);
if(cTkn == ((char)109)) // if the character ''m'' is found
{
fread(&cTkn, sizeof(cTkn), 1, fp);
if(cTkn == ((char)101)) // if the character ''e'' is found
{
fread(&cTkn, sizeof(cTkn), 1, fp);
if(cTkn == ((char)92)) // if the character ''\'' is found
{
// here the complete "\name\" string has been found
while(cTkn != ((char)0))
Here you''re going into an infinite loop, because cTkn is never changed
based on the fread below. It isn''t the fread that''s causing the seg fault,
though; it is your incrementing j past the end of the sName buffer and then
having fread try to write into that location...(well, I guess even just
taking the address has undefined behavior, for the purists)

{
fread(&sName[j], sizeof(cTkn), 1, fp);
j++;
}
}
}
}
}
}
}
}
i++;
}
printf("Read %d characters!\n", i);
printf("Found: %s",sName);
fclose(fp);

return 0;
}
----------------------------------------------------------------




希望让你去。

-leor

Leor Zolman

BD软件
le ** @ bdsoft.com
www.bdsoft.com - C / C ++,Java,Perl& A的现场培训Unix

C ++用户:下载BD Software的免费STL错误消息

Decryptor at www.bdsoft.com/tools/stlfilt.html



Hope that gets you going.
-leor
Leor Zolman
BD Software
le**@bdsoft.com
www.bdsoft.com -- On-Site Training in C/C++, Java, Perl & Unix
C++ users: Download BD Software''s free STL Error Message
Decryptor at www.bdsoft.com/tools/stlfilt.html


2004-02-25 ,spike< jo ** @ ljungh.se>写道:
On 2004-02-25, spike <jo**@ljungh.se> wrote:
我试着写一个应该通过二进制文件读取的程序,搜索字符序列\ name \
然后它应该读取\\\\之后的字符序列
直到遇到NULL字符。


编写一个更通用的函数可以更有用,它可以搜索任何字符串的二进制文件。然后你的程序可以调用这个函数,

传递\\\\
ame \\作为输入。未经测试的代码:


/ *

*接受二进制输入流和字符串作为输入。

*返回true或false取决于是否在输入流中找到字符串

*。

*

*调用者可以稍后使用ftell()找到数字

*扫描的字节数。

* /

int bf_textsearch(FILE * fp,char * s)

{

int index;

int len;

int c;


index = 0;

len = strlen(s) - 1;

while((c = fgetc(fp))!= EOF){

if(c!= s [index]){

index = 0;

ungetc(c,fp);

继续;

}

if(index == len){

返回1;

}

index ++;

}

返回0;

}

但是当我的程序运行时它会得到一个SIGSEGV (分段违规)信号。

什么是错的?
有没有比我更好的方法来解决这个问题(大多数很可能)


你的代码检查或者第一次调用fread()失败,但不是后续调用的
。后续调用可能已设置EOF指示符,

将文件位置指示器保持在不确定状态,因此后续调用fread会导致未定义的行为。


在你最内层的if子句中,你的循环读取文件,直到你找到一个''\ 0''字符。但是,您将所有已读取的字符存储到sName中,这是一个50字符的数组。如果在找到的字符串后的流中

字符的数量大于50,那么你将访问一个超出其定义范围的数组,这个

导致未定义的行为。不要把结果存入

数组。只需丢弃扫描的字符(例如,通过

继续重复使用cTkn变量进行扫描)。

代码:
----- -------------------------------------------------- ---------
int main()
{FILE * fp;
fp = fopen(" demo.dem"," rb") ;

char cTkn;
char sName [50];
int i = 0,j = 0;
while(!(feof(fp)))
{
if(fread(& cTkn,sizeof(cTkn),1,fp))
{
if(cTkn ==((char)92))// if找到角色''\''
{/ fread(& cTkn,sizeof(cTkn),1,fp);


[snip]

while(cTkn!=((char)0))
{/ / fName(& sName [ j],sizeof(cTkn),1,fp);
j ++;
}


[snip]

--- -------------------------------------------------- -----------
Im trying to write a program that should
read through a binary file searching for the character sequence "\name\"
Then it should read the characters following the "\name\" sequence
until a NULL character is encountered.
It might be more useful to write a more general function that can search
a binary file for any string. Your program can then call this function,
passing "\\name\\" in as input. Untested code:

/*
* Accept binary input stream and string as input.
* Return true or false depending on whether the string
* is found in the input stream, or not, respectively.
*
* Caller can use ftell() to later find the number
* of bytes scanned.
*/
int bf_textsearch(FILE *fp, char *s)
{
int index;
int len;
int c;

index = 0;
len = strlen(s) - 1;
while ((c = fgetc(fp)) != EOF) {
if (c != s[index]) {
index = 0;
ungetc(c, fp);
continue;
}
if (index == len) {
return 1;
}
index++;
}
return 0;
}
But when my program runs it gets a SIGSEGV (Segmentation vioalation) signal.

Whats wrong?
And is there a better way than mine to solve this task (most likely)
Your code checks for or failure of the first call to fread(), but not
subsequent calls. The subsequent calls may have set the EOF indicator,
leaving your file-position indicator in an indeterminate state, and so
subsequent calls to fread result in undefined behavior.

In your innermost if-clause, your loop on reading the file until you
find a ''\0'' character. However, you are storing all the characters you
have read into sName, which is an array of 50 char. If the number of
characters in your stream following the found string is larger than 50,
then you are accessing an array outside of its defined bounds, and this
results in undefined behavior. Don''t bother storing the result into
the array. Just discard your scanned characters (for instance, by
continuing to re-use the cTkn variable to scan into).

Code:
----------------------------------------------------------------
int main()
{
FILE *fp;
fp = fopen("demo.dem","rb");

char cTkn;
char sName[50];
int i=0,j=0;
while(!(feof(fp)))
{
if(fread(&cTkn, sizeof(cTkn), 1, fp))
{
if(cTkn == ((char)92)) // if the character ''\'' is found
{
fread(&cTkn, sizeof(cTkn), 1, fp);
[snip]
while(cTkn != ((char)0))
{
fread(&sName[j], sizeof(cTkn), 1, fp);
j++;
}
[snip]
----------------------------------------------------------------




- James



-- James


2月25日星期三2004 16:16:42 GMT,Leor Zolman< le ** @ bdsoft.com>写道:
On Wed, 25 Feb 2004 16:16:42 GMT, Leor Zolman <le**@bdsoft.com> wrote:
while((c = getc(fp))!= EOF&& pos< MAX&& c!=''\''')
while ((c = getc(fp)) != EOF && pos < MAX && c != ''\0'')




糟糕,应该是...&& pos< MAX - 1 ...

-leor


Leor Zolman

BD软件
le ** @ bdsoft.com
www.bdsoft.com - C / C ++,Java,Perl& Cn的现场培训Unix

C ++用户:下载BD Software的免费STL错误消息

Decryptor at www.bdsoft.com/tools/stlfilt.html



Whoops, that was supposed to be ... && pos < MAX - 1 ...
-leor

Leor Zolman
BD Software
le**@bdsoft.com
www.bdsoft.com -- On-Site Training in C/C++, Java, Perl & Unix
C++ users: Download BD Software''s free STL Error Message
Decryptor at www.bdsoft.com/tools/stlfilt.html


这篇关于读取二进制文件,直到“\ name\”;遇到了......的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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