c语言写入csv 逗号字符串,[转]C语言处理CSV文件的方法,以及kdd cup的简单说明...

C语言处理CSV文件的方法

什么是CSV文件

CSV是 Comma-separated values

(逗号分隔值)的首字母缩写,它通常是以逗号且不仅限于逗号分隔各个值,我们都叫他CSV。看下面的例子:

China, Shanghai, Pudong,

Zhang San, 200000, 1234567

BMW; GER; 300000; RMB;

i530

从上面两个例子可以看出,可以用不同的分隔符来分隔数据;数据的类型可以不同;长度任意。

由多行这样的CSV组成的文件叫做CSV文件(逗号分隔值文件)。当然,他们必须用同样的分隔符,对应每一列的数据要有相同的含义,不然这个文件就是无意义的。CSV文件可以直接用Microsoft

Office中的Excel打开,这里不讨论Windows下的操作。

C语言编程处理CSV文件

通常CSV文件中包含大量有用信息,而且有时数据量庞大,一个数据文件会达到1G的大小,一般都是日志等重要信息。对CSV文件的处理也有很多方法,常见的就是用Bash,

Python, Perl

等脚本语言来处理。这里提供一种用C语言处理CSV文件的方法。以下过程都是在Linux环境下进行的,Windows用户请注意移植。

C语言标准库中有一个字符串(string.h)函数 strtok ,它的原型是

char *strtok( char *s,

const char *ct );

它以 ct 中的字符为分界符,将字符串 s 分成许多记号。第一次调用时,它搜索 s ,找到不包含ct的第一个记号,将 s

中的下一个字符替换为 ‘/0’ ,并返回指向记号的指针。随后调用 strtok 函数时(由 s 的值是否为NULL指示),返回下一个不包含 ct

中字符的记号。当 s 中没有这样的记号时,返回NULL 。每次调用时的 ct 可以不同。

注意红色标记的部分,这个函数的使用方法是(假设以逗号为分隔符):

char str[] = “Life is

like, a box of chocolate, you never, know what you’re, gonna

get”;

char delims[] = “,”;

char *result = NULL;

result = strtok( str, delims );

while( result != NULL ) {

printf( “%s /n”, result );

result = strtok( NULL, delims

);

}

OUTPUT:

life is like

a box of chocolate

you never

know what you’re

gonna get

这里只是单纯的把CSV分解成独立的可供后续处理的字符串,下面介绍一个复杂些的例子。

KDD CUP 99 DATASET

Preprocessing KDDCUP99数据集的预处理

关于KDD CUP 99数据集的介绍请看这里。

KDD CUP

99数据集是网络入侵检测(NIDS)的标准测试集,为IDS研究人员提供训练数据集和测试数据集,以期比较不同入侵检测方法的优劣。尽管该数据集是1998年建立的,但仍是现在研究最多的IDS数据集。

该数据集每一行就是由tcpdump采集并处理的一条记录,包含了41个特征值和1个攻击类型说明,每一个特征之间用逗号分隔,最后用逗号分隔攻击类型。训练集的一个1/10子集共有

494,021 条记录,是一个标准CSV文件。下面是其中3条记录:

0,icmp,ecr_i,SF,1032,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,511,511,0.00,0.00,/

0.00,0.00,1.00,0.00,0.00,255,255,1.00,0.00,1.00,0.00,0.00,0.00,0.00,0.00,smurf

0,tcp,http,SF,287,41018,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,15,32,0.00,0.00,/

0.07,0.03,1.00,0.00,0.16,61,255,1.00,0.00,0.02,0.01,0.00,0.00,0.02,0.00,normal

0,icmp,eco_i,SF,18,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0.00,0.00,0.00,/

0.00,1.00,0.00,0.00,3,15,1.00,0.00,1.00,0.27,0.00,0.00,0.00,0.00,ipsweep

由于数据的类型比较复杂,有离散类型(比如协议类型tcp,

upd…)和连续类型(持续时间,发送包数量等),要分开处理。预处理过程分两步:1. 映射。将符号型的数据(symbolic-valued attribute)映射到数值型数据(numeric-valued

attribute)。2. 归一化。将所有数据都调整到 [0.0 , 1.0]区间内。

由于strtok只能处理字符串类型数据,需要用 atoi , atol, atof

字符串转换函数来将字符串转换为数字,方便归一化处理。

….

while ( fgets( line,

length, fp ) != NULL ) { //read

a single line of dataset

result = strtok(line,

“,”); //read

the first attribute

for ( i = 0; i < 42; i++ )

{

switch (i) { //mapping and scaling the 41 attributs + 1 class respectively

case

0: //duration, continuous, [0, 58329]

printf(“%.2f,”, float(atoi(result))/DURATION);

break;

case

1: //protocal_type, symbolic, 3

printf(“%.2f,”, protocal_type(result));

break;

} //switch end

} //for end

result = strtok(NULL,

“,”); //continue reading next attribute

} //while end

每次读入一行数据文件,用strtok分隔出每个特征,再用switch判断是哪一个特征,然后对相应特征进行归一化处理。

总结

C语言对处理这种纯粹文本的数据不太擅长,虽然运行速度没的说,但编起来确实比较麻烦。建议还是用脚本语言配合正则表达式来做这种数据处理。

我程序中使用switch来判断特征值类型,由于一共有41个特征,所以比较麻烦,如果有简单的匹配方法,敬请E-mail我。

参考文献

1. http://www.elook.org/programming/c/strtok.html

2. The C Programming Language. 2nd Edition by

K&R

3. KDDCUP99

http://kdd.ics.uci.edu/databases/kddcup99/kddcup99.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值