matlab 中的textscan

textread 与textscan的区别

textscan更适合读入大文件;

textscan可以从文件的任何位置开始读入,而textread 只能从文件开头开始读入;

textscan也可以从上一次textscan结束的位置开始读入,而textread不能;

textscan只返回一个数组(其实应该说是一个细胞矩阵),而textread要返回多个数组(嗯嗯);

textscan提供更多转换读入数据的选择;

textscan提供给用户更多的配置参数。

来源:http://blog.sina.com.cn/s/blog_9e67285801010buf.html

textscan函数

功能:读格式的数据从文本文件或字符串。适用于具有多行文字说明文本数据文件。

————————————————————————————————————————

基本用法:

C = textscan(fid, \'format\')

C = textscan(fid, \'format\', N)

C = textscan(fid, \'format\', \'param\', value)

C = textscan(fid, \'format\', N, \'param\', value)

C = textscan(str, ...)

[C, position] = textscan(...)

——————————————————————————————————————

输入参数

fid 为fopen命令返回的文件标识符,这也是和textread的最大不同之处

需要注意的一点是,fid类似一个指针,其指向的位置会随着textscan的操作而改变,参见例9

format 是一个字符串变量,表示读取数据及数据转换的规则,具体见format.txt

N 读取N次,一般为行数

输出参数

输出一个细胞数组C

基本与textread语法相同

.............................................................................

例1:

\'mydata1.txt文件如下

Sally Level1 12.34 45 1.23e10 inf Nan Yes 5.1+3i

Joe Level2 23.54 60 9e19 -inf 0.001 No 2.2-.5i

Bill Level3 34.90 12 2e5 10 100 No 3.1+.1i

读入:

>> fid = fopen(\'mydata1.txt\');

C = textscan(fid, \'\'%s%s%f32%d8%u%f%f%s%f\');

fclose(fid);

>> C

C =

Columns 1 through 5

{3x1 cell} {3x1 cell} [3x1 single] [3x1 int8] [3x1 uint32]

Columns 6 through 9

[3x1 double] [3x1 double] {3x1 cell} [3x1 double]

输出C为1*9的细胞数组,每个数组中存放每列的数据

..................................................................

例2:

可设置读取长度,具体是,在%和格式符之间插入数字N,代表你要读入几个数值(有点问题)

如:

>> dd=\'let us go\';

>> ddd=textscan(dd,\'\\')

ddd =

\'let u\'

对于myfileli6.txt

Sally Type1 12.34 45 Yes

Joe Type2 23.54 60 No

Bill Type1 34.90 12 No

>> fmyfileli6.txt\');

>> data=textscan(fid,\'%s%s%f%f%s\',3); %正常读入数据

....................注意对于数据省略操作应该跳过被省略部分.........

例:

str = \'0.41 8.24 3.57 6.24 9.27\';

C = textscan(str, \'%3.1f \');

C会出现这种情况

C=

0.400000000000000

1

8.20000000000000

4

3.50000000000000

7

6.20000000000000

4

9.20000000000000

7

>> C = textscan(str, \'%3.1f %*1d\');

>> C{1}

ans =

0.4000

8.2000

3.5000

6.2000

9.2000

......................................................

例3:读取不同格式的数据

scan1.txt如下

09/12/2005 Level1 12.34 45 1.23e10 inf Nan Yes 5.1+3i

10/12/2005 Level2 23.54 60 9e19 -inf 0.001 No 2.2-.5i

11/12/2005 Level3 34.90 12 2e5 10 100 No 3.1+.1i

现在把scan1.txt读入

fid = fopen(\'scan1.dat\');

C = textscan(fid, \'%s %s %f32 %d %u %f %f %s %f\');

fclose(fid);

输出C为一个1*9的细胞矩阵

C{1} = {\'09/12/2005\'; \'10/12/2005\'; \'11/12/2005\'} class cell

C{2} = {\'Level1\'; \'Level2\'; \'Level3\'} class cell

C{3} = [12.34; 23.54; 34.9] class single

C{4} = [45; 60; 12] class int8

C{5} = [4294967295; 4294967295; 200000] class uint32

C{6} = [Inf; -Inf; 10] class double

C{7} = [NaN; 0.001; 100] class double

C{8} = {\'Yes\'; \'No\'; \'No\'} class cell

C{9} = [5.1+3.0i; 2.2-0.5i; 3.1+0.1i] class double

C{5}中的4294967295指的是32位系统无符号整型的最大值2^32-1

也可以把C{1}中的内容分别读入

>> fid = fopen(\'scan1.txt\');

>> C = textscan(fid, \'%f/%f/%f %s %u %f %f %s %f\');

>>fclose(fid);

>> C{1}\'

ans =

9 10 11

>> C{2}\'

ans =

12 12 12

>> C{3}\'

ans =

2005 2005 2005

........一下相同.....

............................................................

例4:移除字符串

对于上述scan1.txt 如果想忽略Level而直接读取数字

>> fid = fopen(\'scan1.txt\');

>> C = textscan(fid, \'%s Level%u8 %u %f %f %s %f\');

>>fclose(fid);

>> C{2}\'

ans =

1 2 3

....................................................................

例5:读取某列

>> fid = fopen(\'scan1.txt\');

dates = textscan(fid, \'%s %*[^\n]\');

fclose(fid);

>> dates{1}

ans =

\'09/12/2005\'

\'10/12/2005\'

\'11/12/2005\'

dates是一个1*1的细胞矩阵

%[^\n] 就是一直读到行尾。

如:

>>fid = fopen(\'scan1.txt\');

>>dates = textscan(fid, \'%s %[^\n]\');

>>fclose(fid);

>>dates{1}\'

ans =

\'09/12/2005\' \'10/12/2005\' \'11/12/2005\'

>> dates{2}

ans =

\'Level1 12.34 45 1.23e10 inf Nan Yes 5.1+3i\'

\'Level2 23.54 60 9e19 -inf 0.001 No 2.2-.5i\'

\'Level3 34.90 12 2e5 10 100 No 3.1+.1i\'

%*[^\n] 就是从当前直接跳到行尾。

% *是一个跳过符号,表示跳过该位

............................................................................

例6:

处理存在空数据

实用分节符delimiter 和空值符EmptyValue

对于exm5.txt

1, 2, 3, 4, , 6

7, 8, 9, , 11, 12

读取数据,空数据用-inf替换

>> fid = fopen(\'exm5.txt\');

C = textscan(fid, \'%f %f %f %f %f %f\', \'delimiter\', \',\',\'EmptyValue\', -Inf);

fclose(fid);

>> data=cell2mat(C)

data =

1 2 3 4 -Inf 6

7 8 9 -Inf 11 12

...............................................................................

例7

跳过所有注释,选择性的把某些输入置 空

exm6.txt文件如下:

abc, 2, NA, 3, 4

// Comment Here

def, na, 5, 6, 7

现在我们想要第二行的注释,并且把其中的 NA na 置为NAN

>> fid = fopen(\'exm6.txt\');

>>C = textscan(fid, \'%s %n %n %n %n\', \'delimiter\', \',\', \'treatAsEmpty\', {\'NA\', \'na\'}, \'commentStyle\', \'//\');

>>fclose(fid);

>> C{1}

ans =

\'abc\'

\'def\'

>> C{2:5}

ans =

2

NaN

ans =

NaN

5

ans =

3

6

ans =

4

7

.................................................................................

例8:

处理重复的分隔符,把重复分隔符认为成一个分隔符

exm8.txt如下:

1,2,3,,4

5,6,7,,8

现在我们想把重复分隔符合并认为成单个分隔符,我们采用MultipleDelimsAsOne参数把其设置为1

% multiple 多个 delims 分隔符 as one

>> clear

>> fid = fopen(\'exm8.txt\');

C = textscan(fid, \'%f %f %f %f\', \'delimiter\', \',\', \'MultipleDelimsAsOne\', 1);

fclose(fid);

>> data=cell2mat(C)

data =

1 2 3 4

5 6 7 8

..........................................................................

例9: CollectOutput Switch的应用

CollectOutput switch的默认值是0(false)textscan函数把每列的数据放在一个细胞矩阵中

>> clear

>> fid = fopen(\'grades.txt\');

C_text = textscan(fid, \'%s\', 4, \'delimiter\', \'|\'); % read column headers

>>

C_data0 = textscan(fid, \'%d %f %f %f\') % read numeric data 在此fid指向了第二行

C_data0 =

[4x1 int32] [4x1 double] [4x1 double] [4x1 double]

>> C_data0{1:4}

ans =

1

2

3

4

ans =

91.5000

88.0000

76.3000

96.4000

ans =

89.2000

67.8000

78.1000

81.2000

ans =

77.3000

91.0000

92.5000

84.6000

现在我们利用CollectOutput switch置为1,这样就可以把同类数据放在同一个细胞数组下

>> frewind(fid); %把fid指到文档开始位置

C_text = textscan(fid, \'%s\', 4, \'delimiter\', \'|\');

C_data1 = textscan(fid, \'%d %f %f %f\',\'CollectOutput\', 1)

C_data1 =

[4x1 int32] [4x3 double]

>> C_data1{1}

ans =

1

2

3

4

>> C_data1{2}

ans =

91.5000 89.2000 77.3000

88.0000 67.8000 91.0000

76.3000 78.1000 92.5000

96.4000 81.2000 84.6000

......................................................................................

其实还有两个对字符串的操作,鉴于不经常用,故此略去,欢迎留言补充。

源文档 <http://blog.sina.com.cn/s/blog_9e67285801010buf.html>