我来跟你讲讲文本格式吧
在Unix/Linux/MAC中,文本文件的行间隔用 \n
而Windows中用 \r\n
但用户是无须关心这种差别的,因为只要使用文本格式(而非二进制格式)打开文件,Unix/Linux/MAC下会将\n原样读出来写进去,而Windows会将文本中的\r\n读成\n,而将写入的\n写成\r\n。也就是,库函数本身已经做了相应的转化。
但你不能将Unix/Linux/MAC中文本格式用Windows库处理,反之亦不可,否则就是牛头对马嘴了。
而你给的这个3.txt中,文件间隔竟然用的是\r,^_^
为了适合你这个文件,我将代码改一下,你以后换文件格式时记得改代码,也就是case '\r': case '\n':那两行

程序代码:
#include <stdio.h>
#include <string.h>
#include <assert.h>
void dna8_val2str( unsigned long val, char str[8] )
{
assert( val < (1ul<<(8*2)) );
for( size_t i=0; i<8; ++i )
{
str[7-i] = "agct"[val%4];
val >>= 2;
}
}
int main()
{
unsigned long words = 0;
unsigned long numbers[65536] = { 0 };
// 处理
FILE* fin = fopen( "3.txt", "r" );
if( !fin )
return 1;
int bav = 0;
unsigned long val = 0;
for( int c; c=fgetc(fin), c!=EOF; )
{
switch( c )
{
case '@': // 遇到@则结束
break;
case '\r':
//case '\n':
++words;
continue;
case 'a':
case 'g':
case 'c':
case 't':
val = ((val<<2)&0xFFFF) | (c%36%5);
if(bav<7) // 不足8个有效字符时先等等
++bav;
else
++numbers[val];
break;
default: // 出现了agct之外的字符
long pos = ftell(fin)-1;
if( c>0x20 && c<0xFF ) // 可显示的字符,就显示其本身
printf( "--- 0x%08lX处出现非法字符\'%c\'\n", pos, (char)c );
else // 不可显示的字符,就显示其对应的ASCII值
printf( "--- 0x%08lX处出现非法字符0x%02hhX\n", pos, (char)c );
}
}
fclose( fin );
// 输出
FILE* fout = fopen( "result2.txt", "w" );
if( !fout )
return 3;
fprintf( fout, "The Number of total words are %ld\n", words );
fprintf( fout,"The Expect Number words are %f\n", words/65536.0 );
for( int i=0; i<65536; ++i )
{
// if( numbers[i] !=0 )
{
char str[8];
dna8_val2str( i, str );
fprintf( fout, "%.8s\t%ld\t%f\n", str, numbers[i], numbers[i]/65536.0 );
}
}
fclose( fout );
printf( "处理完毕\n" );
return 0;
}另外注意一下,我用unsigned long计数,也就是数量不可以超过4亿。如果数量超过,你得改类型,还得改相应的ftell
[
本帖最后由 rjsp 于 2012-11-15 09:02 编辑 ]