小弟想试着做一个文本文件分割小程序,遇到了下列问题!

xuen30 2011-08-15 01:31:59
我想实现这样的效果:
1、由用户输入想把文本文件要分割的份数。
如:要把笑话.txt分成4份。
2、程序运行后,会自生成笑话1.txt,笑话2.txt,笑话3.txt,笑话4.txt
本以为程序不难完成,但在编写中遇到这样的一个问题:
1、首先,以二进制模式打开笑话.txt,我想通过读取笑话.txt,总字节大小(3359kb),然后把它除以4,找到每次读的字数后,然后再写在笑话1.txt中,但是这样会发现,不是分成4份,而是分成了3份,并且每份字数相差不少。
到底有没有好的方法:
代码如下:

Private Sub Command1_Click()
Dim a As Integer
Dim b As Integer
Dim c As Integer
Dim i As Integer
Dim tx As String
Dim nm As String
i = 0
Com1.ShowOpen
Com1.DialogTitle = "打开文件"
Com1.Filter = "文本文件|*.txt|"
Open Com1.FileName For Binary As #1
a = LOF(1) / 4
tx = String$(a, " ")
Get #1, 1, tx
b = Seek(1)


Text1.Text = tx
nm = Left(Com1.FileName, Len(Com1.FileName) - 4)
Open nm & "5.txt" For Output As #2
Print #2, tx

End Sub

Private Sub Command2_Click()
Unload Me
End Sub

...全文
229 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
xuen30 2011-08-17
  • 打赏
  • 举报
回复
谢谢猴哥及各位好汉的热情,我已试过猴哥的方法,它是按字数分的,这样会现同一行的内容会分到不同的文件中,可不可以按行分,大家想想吧
xuen30 2011-08-17
  • 打赏
  • 举报
回复
根据MSDN所讲:
"要将整个文件复制到变量,请使用InputB 函数将字节从文件复制到变量。因为InputB函数返回一个 ANSI字符串,您必须使用 StrConv 函数将 ANSI 字符串转换为一个如 UNICODE 字符串:
LinesFromFile = StrConv(InputB(LOF(FileNum), FileNum), vbUnicode)"

注意 对于文本文件中包含的字节数据要使用 InputB 函数。对于 InputB 来说,number 指定的是要返回的字节个数,而不是要返回的字符个数。那么这一句InputB(LOF(1), 1), 应该理解为从字节1开始,返回文本文件的所有字节
xuen30 2011-08-17
  • 打赏
  • 举报
回复
再一次谢谢各位
xuen30 2011-08-17
  • 打赏
  • 举报
回复
又大补了一下split函数:
作用:返回一个从零开始的一维数组,其中包含指定数量的子字符串。
Expression
必选项。字符串表达式,包含子字符串和分隔符。如果 Expression 是零长度的字符串 (""),Split 函数将返回长度为一的数组,其中包含一个空字符串。
Delimiter
可选项。单个字符,用于标识子字符串的界限。如果省略了 Delimiter,则假定空白字符 ("") 为分隔符。如果 Delimiter 为零长度字符串,则返回包含整个 Expression 字符串的单元素数组。
txtmp = Split(tx, vbCrLf)
这句话的作用是,从把tx的内容以回车符为分界线,赋给一维数组txtmp,行数吗就比数组元素多1,然后再取每个分文件的行数
chinaboyzyq 2011-08-17
  • 打赏
  • 举报
回复

Private Sub Command1_Click()
Dim a As Integer
Dim b As Integer
Dim c As Integer
Dim i As Integer
Dim tx As String
Dim txtmp() As String
Dim nm As String
Text1 = "": Text2 = "": Text3 = "": Text4 = "":
Com1.ShowOpen
Com1.DialogTitle = "打开文件"
Com1.Filter = "文本文件|*.txt|"
Open Com1.FileName For Binary As #1
tx = StrConv(InputB(LOF(1), 1), vbUnicode)
txtmp = Split(tx, vbCrLf)
a = UBound(txtmp) + 1
b = IIf(a Mod 4, Int(a / 4) + 1, a / 4)


txtmp数组包含总的文本,每元素一个包含一个三硬回车行的内容(不包含回车).
a是总行数,b是每个文件能分的行数,你自已去处理连接和存盘问题吧。
worldy 2011-08-16
  • 打赏
  • 举报
回复
这有什么困难啊?
在扫描vbCrlf的时候,使用一个数组或者集合记录vbCrlf出现的位置,分割不就是将关注的行位置之间的数据取出来而已?
xuen30 2011-08-16
  • 打赏
  • 举报
回复
谢谢猴哥的热情讲解。不过小弟实在是资质太差,里面有些问题学没想通
1、a = IIf(Len(tx) Mod 4, Int(Len(tx) / 4) + 1, Len(tx) / 4)
这个我上网搜了一上明白了,我理解的意思是:如果文本内容平均分成4份,如果有余数就把整数部分加1,如果没有则取第二部分值。
2、但是我对于tx = StrConv(InputB(LOF(1), 1), vbUnicode)不明白,什么意思?

上网一查:
StrConv(string, conversion, LCID)
string 必要参数。要转换的字符串表达式。
conversion 必要参数。Integer。其值的和决定转换的类型。
LCID 可选的。如果与系统LocaleID不同,则为LocaleID(系统LocaleID为缺省值。)

这句话不明白?
vbUnicode 64 根据系统的缺省码页将字符串转成 Unicode
chinaboyzyq 2011-08-16
  • 打赏
  • 举报
回复
对以上回的想了想,如果中英文混排还是有可能出错的,如果文件不是很大,可以先全部读进来,转换后再分。

Private Sub Command1_Click()
Dim a As Integer
Dim b As Integer
Dim c As Integer
Dim i As Integer
Dim tx As String
Dim nm As String

Com1.ShowOpen
Com1.DialogTitle = "打开文件"
Com1.Filter = "文本文件|*.txt|"
Open Com1.FileName For Binary As #1
tx = StrConv(InputB(LOF(1), 1), vbUnicode)

a = IIf(Len(tx) Mod 4, Int(Len(tx) / 4) + 1, Len(tx) / 4)

For b = 1 To 4
Me("Text" & b).Text = Mid(tx, a * (b - 1) + 1, a)

Next
Close #1


End Sub

chinaboyzyq 2011-08-16
  • 打赏
  • 举报
回复
修改一下:
a = IIf(LOF(1) Mod 4, Int(LOF(1) / 4) + 1, LOF(1) / 4)
chinaboyzyq 2011-08-16
  • 打赏
  • 举报
回复
假设窗体上有文本框text1~text4

Private Sub Command1_Click()
Dim a As Integer
Dim b As Integer
Dim c As Integer
Dim i As Integer
Dim tx() As Byte
Dim nm As String

Com1.ShowOpen
Com1.DialogTitle = "打开文件"
Com1.Filter = "文本文件|*.txt|"
Open Com1.FileName For Binary As #1
a = LOF(1) / 4 + 0.5
ReDim tx(a)

For b = 1 To 4
Get #1, Seek(1), tx
Me("Text" & b).Text = StrConv(tx, vbUnicode)

Next
Close #1


End Sub

赵4老师 2011-08-16
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 chinaboyzyq 的回复:]
对以上回的想了想,如果中英文混排还是有可能出错的,如果文件不是很大,可以先全部读进来,转换后再分。

VB code

Private Sub Command1_Click()
Dim a As Integer
Dim b As Integer
Dim c As Integer
Dim i As Integer
Dim tx As String
Dim nm As String……
[/Quote]
支持。用InputB函数才是正解。
c_cyd2008 2011-08-16
  • 打赏
  • 举报
回复
这其实没有万全的分割法的;
1、按字节分,这肯定是不行的,分割出来的文档有可能不可读;
2、按字分,可以确保文档可读,但会造成一行(或一段)分割在不同文档中;
3、按行(或段落),(行和段落其实是Word等排版软件的概念,这里把行或段理解成是以VbCrLf分割的),这种方式看起来不错,不过如果遇到长行(大段)就麻烦了,极端的情况是一个文件只有一大段,那就无法分割了。
总的来看,程序好写,关键是LZ要对这些方式的取舍作出决定。
xuen30 2011-08-15
  • 打赏
  • 举报
回复
首先,再次谢谢朋友们
楼5和楼6的办法,我都想过也试了。
楼Veron_04朋友,我在用二进制打开文本文件时,或用指针分,或用字节分,都不行。
但指针这个东西,却是在分割时很有用。
楼6worldy朋友,获取文本文件的行数确实不难,我也成功了获取了行数,但是,如果是要4行为一个分割文本,第二次,取5至9行到第二个分割文件中,这是我遇到的问题!

不过,反复思考按行来分隔,确实是一个好的方法,只不过还没能实现,大家再想想办法吧!我再试试
worldy 2011-08-15
  • 打赏
  • 举报
回复
[Quote=引用楼主 xuen30 的回复:]
我想实现这样的效果:
1、由用户输入想把文本文件要分割的份数。
如:要把笑话.txt分成4份。
2、程序运行后,会自生成笑话1.txt,笑话2.txt,笑话3.txt,笑话4.txt
本以为程序不难完成,但在编写中遇到这样的一个问题:
1、首先,以二进制模式打开笑话.txt,我想通过读取笑话.txt,总字节大小(3359kb),然后把它除以4,找到每次读的字数后,然后再写在笑话1.txt……
[/Quote]

我感觉,这样的分隔方法不好,肯定99.99%会将一个段落分成了两个段落,更郁闷的是,还很可能将一个汉字拆成了两半,结果,第二段起,全部乱码!

我的建议是,首先扫描文档,计算出所有的行数(段落可能没有标记,只能以行来分隔,计算这个不难,扫描回车换行符号的个数),然后,确定每部分的行数,再按行数进行分隔,这样能确保一个段落不会被分成两个,一个字符不会被分成两半

供参考!
贝隆 2011-08-15
  • 打赏
  • 举报
回复
使用open采用Binary方式打开文件,然后分割。
xuen30 2011-08-15
  • 打赏
  • 举报
回复
感谢三位的回复,但是从文本文件中读取字数,要用到filesysobject,如果文本文件中只有文字和标点还好,如果即有回车、又有空行,这样统计出来的字数就不准确了,怎么办
greatbody 2011-08-15
  • 打赏
  • 举报
回复
a=字数/文件数 1532/7=218.85=219
If a*文件数>=字数 then
b=a
else
b=a+1
end if
b即为得到的需要分割的每个文件的大小最大值
然后根据这个值,参考网上有的:根据字符数分割文本文件
c_cyd2008 2011-08-15
  • 打赏
  • 举报
回复
你应该按字数分割,而不是按字节数分割,你还要处理文本文件的编码,不同的编码每个字所占的字节数也是不一样的。
of123 2011-08-15
  • 打赏
  • 举报
回复
1 除法的余数,可能被你丢掉。

2 你这样的切法,可能使中文等东亚文字变成乱码。

7,763

社区成员

发帖
与我相关
我的任务
社区描述
VB 基础类
社区管理员
  • VB基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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