能帮助我解决这个问题的朋友我给他500分

poemlake 2003-12-08 11:59:56
我遇到一个难题,我是学pb的,对于C语言一点也不懂,我往27c512 的eprom中写文件(文件最大512K),这个文件为扩展名为bin的,是由几个扩展名为.e80的二进制文件合并在一起的,反过来,用eprom读写器读出来以后,为一个整体的二进制文件为.bin 现在要做两个程序,一个是把几个文件(001.e80,002.e80 003.e80 ......)合并在一起,存成.bin文件,一个是把这个 bin文件再分成几个文件,分别存成单个e80文件(001.e80,002.e80,003.e80..... )我注意过,每个e80的文件结尾是 80 80
但数据中间也有 80 80 但可以判断每个e80文件的结尾是80 80 ff ,不能增加e80文件的长度,
我把单个的e80文件和bin文件上传一个打包文件
http://go.6to23.com/poemlake/e80.rar
有哪位热心的朋友帮写一段代码,我在pb中做了一半,但速度太慢,所以想用C,有哪位朋友提供帮助的,我给500分,分不够,我另加,QQ:70237855
...全文
31 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
poemlake 2003-12-12
  • 打赏
  • 举报
回复
短歌兄,另一位兄弟的分少,多给他点分,我用的是他的代码,你的我没弄明白,不知道怎么使用。我可是一点也不懂C啊
短歌如风 2003-12-11
  • 打赏
  • 举报
回复
呵呵……又是VC害人。
没有错误,只有警告,VC处理不了模板生成的长标识符,但不影响使用。
在第一行加一句:
#pragma warning(disable : 4786)
就可以去掉这个警告。
此外主函数最后就是少了一句return 0。
njuhuangmy 2003-12-11
  • 打赏
  • 举报
回复
#include <stdio.h>
#include <string.h>
#include <stdio.h>
#include <io.h>

unsigned char mark[16];
unsigned char mark2[10];

unsigned int notend(unsigned char* rbuf)
{
int i;
// i 0 ---- 7

mark2[0] = 0x80;
mark2[1] = 0x80;

memset(mark2 + 2, 0xff, 8);

for (i = 0; i < 7; i++)
{
if (memcmp(rbuf++, mark2, 10) == 0)
return i + 10;
}

return 16;
}

void combine(int n, char **fn)
{
int i, rnum;

unsigned char wbuf[16];

FILE* out = fopen(fn[n + 1], "wb+");

for (i = 1; i <= n; i++)
{
FILE* in = fopen(fn[i], "rb+");

while (!feof(in))
{
memset(wbuf, 0xff, 16);
rnum = fread(wbuf, 1, 16, in);

if (rnum != 0)
fwrite(wbuf, 1, 16, out);
}

fclose(in);
fwrite(mark, 1, 16, out);
}

fclose(out);
}

void separate(char *fn)
{
int i = 0, rnum, wnum;

// less than 10 files, filename is less than 30 characters
char e80[10][30] = {"001.e80", "002.e80",
"003.e80", "004.e80",
"005.e80", "006.e80",
"007.e80", "008.e80",
"009.e80", "010.e80"};

unsigned char rbuf[16];

FILE* in = fopen(fn, "rb+");

while ( (i < 10) && (!feof(in)) )
{
FILE* out;

rnum = fread(rbuf, 1, 16, in);
if ((rnum > 0) && (memcmp(rbuf, mark, 16) != 0))
/*上面这一行被修改了*/
out = fopen(e80[i++], "wb+");

while (!feof(in))
{
if (memcmp(rbuf, mark, 16) != 0)
{
wnum = notend(rbuf);
fwrite(rbuf, 1, wnum, out);
fread(rbuf, 1, 16, in);
}
else
break;
}
fclose(out);
}

fclose(in);
}


int main(int argc, char* argv[])
{
memset(mark, 0xff, 16);

if (argc == 1)
{
printf("Usage: cmd filename[filename......]\n");
return 1;
}
else if (argc == 2)
{
puts("separate .e80 from .bin\n");
separate(argv[1]);
return 0;
}
else
{
puts("combine .e80 to .bin\n");
combine(argc - 2, argv);
return 0;
}
}

呵呵,你分真多:)
poemlake 2003-12-08
  • 打赏
  • 举报
回复
我已上传了e80.rar文件
poemlake 2003-12-08
  • 打赏
  • 举报
回复
编译的时候出错,也没提示错在哪啊 我用vc6.0编译
poemlake 2003-12-08
  • 打赏
  • 举报
回复
楼上的大哥,我先看看,你别急啊,我对C不懂,我慢慢看
短歌如风 2003-12-08
  • 打赏
  • 举报
回复
#include <fstream>
#include <string>
#include <iterator>
#include <vector>
#include <sstream>
#include <iomanip>

//下面两个头文件用于输出分割生成的文件名。如果不需要可以不用。
#include<iostream>
#include<algorithm>

template<typename T>
void merge_file(T begin, T end, const std::string & dest_name)
{
std::ofstream dest(dest_name.c_str(), std::ios_base::trunc|std::ios_base::binary);
while (begin != end)
{
std::ifstream src(begin->c_str(), std::ios_base::binary);
dest << src.rdbuf();
std::streamsize pos = dest.tellp();
for(unsigned i = pos % 16; i < 32; ++i)
dest.put('\xff');
++begin;
}
std::streamsize pos = dest.tellp();
for(unsigned i = pos; i < 64*1024; ++i)
dest.put('\xff');
}

//最后一个参数用于输出分割生成的文件名。如果不需要可以不用。
//不用的话就可以写成:void split_file(const std::string & src_name, const std::string & dest_prefix, const std::string& dest_suffix)
template <typename T>
void split_file(const std::string & src_name, const std::string & dest_prefix, const std::string& dest_suffix, T begin)
{
std::ifstream src(src_name.c_str(), std::ios_base::binary);
unsigned state = 0xb;
std::ofstream dest;
unsigned dest_no = 1;
char ch;
src.get(ch);
while (src)
{
switch((state << 8) | static_cast<unsigned char>(ch))
{
case 0x0180: state = 2; dest.put(ch);break;//第一个80
case 0x0280: state = 3; dest.put(ch);break;//80 80
case 0x03ff: state = 4; dest.put(ch);break;//80 80 ff
case 0x04ff: state = 5; dest.put(ch);break;//80 80 ff ff
case 0x05ff: state = 6; dest.put(ch);break;//80 80 ff ff ff
case 0x06ff: state = 7; dest.put(ch);break;//80 80 ff ff ff ff
case 0x07ff: state = 8; dest.put(ch);break;//80 80 ff ff ff ff ff
case 0x08ff: state = 9; dest.put(ch);break;//80 80 ff ff ff ff ff ff
case 0x09ff: state = 0xa; dest.put(ch);break;//80 80 ff ff ff ff ff ff ff
case 0x0aff: state = 0xb; dest.put(ch);dest.close();break;//8080后第8个ff,文件结束
case 0x0bff: state = 0xb; break;
case 0x0b00://原文件开始后或是8080ffffffff……后的第一个00,创建新的输出文件
{
std::stringstream dest_name;
dest_name << dest_prefix <<std::setw(3) << std::setfill('0') << dest_no ++ << dest_suffix;

dest.open(dest_name.str().c_str(), std::ios_base::trunc|std::ios_base::binary);
state = 1;
dest.put(ch);
*begin++ = dest_name.str();//用于输出分割生成的文件名。如果不需要可以不用。
state = 0;
break;
}
default: state = 1; dest.put(ch);break;
}
src.get(ch);
}
}

std::string infiles[4] = {
"C:\\Downloads\\e80\\001.e80",
"C:\\Downloads\\e80\\002.e80",
"C:\\Downloads\\e80\\003.e80",
"C:\\Downloads\\e80\\004.e80"};
int main()
{
//合并
merge_file(infiles, infiles+4, "C:\\Downloads\\e80\\e80_2.bin");

//分割
std::vector<std::string> filenames;
std::insert_iterator<std::vector<std::string> > first (filenames, filenames.end());
split_file("C:\\Downloads\\e80\\e80_2.bin", "C:\\Downloads\\e80\\e", ".e80", first);

//输出分割生成的文件名。
std::ostream_iterator<std::string> outit(std::cout, "\n");
std::copy(filenames.begin(), filenames.end(), outit);
}
poemlake 2003-12-08
  • 打赏
  • 举报
回复
上传的文件中
e80.bin是001.e80 002.e80 003.e80三个文件的合并,其它的只是供参考格式
格式你用ultraedit看便知,
每个e80文件结尾都留有空位,这样,机器才能读出第几个文件,
而且留的空位不是固定的,不是必须16 个FF,而是我们一般习惯
往eprom中写的时候,空出一行即16个FF,然后以整行开始写新的e80文件
另外,你注意读每个e80文件,每个e80文件的最后是这样格式的80 80 ff ff ff ff ff ff ff ff
即每个80 80 后面跟着8个'ff' 我重新上传了9个单个的e80文件,你看009.e80就能看出来

你可以用 80 80 ff ff ff ff ff ff ff ff 作为判断结束的条件,但下一个e80文件的开始也要判断的,
每个e80文件的开始是00 00 但是中间也可能有00 00 ,可以判断

ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
00 00
象上面的那样可以判断开始,但分割的时候要把前面的16个ff去掉,
总之你们有什么好方法就用什么方法,也可以用16个FF做判断,
但要把e80的数据原样提出来,即开始 00 00 结尾 80 80 ff ff ff ff ff ff ff ff

64,266

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧