【发布时间】:2019-06-19 12:50:23
【问题描述】:
我正在编写读取包含 DNA 碱基的巨大文本文件的代码,并且我需要能够提取特定部分。该文件如下所示:
TGTTCCAGGCTGTCAGATGCTAACCTGGGG
TCACTGGGGGTGTGCGTGCTGCTCCAGCCT
GTTCCAGGATATCAGATGCTCACCTGGGGG
...
每行 30 个字符。
我有一个单独的文件来指示这些部分,这意味着我有一个 start 值和一个 end 值.所以对于每个 start 和 end 值,我需要在文件中提取相应的字符串。 例如,如果我有 start=10, end=45,我需要存储从第一行 (C) 的第 10 个字符开始并在单独的临时文件中的第 2 行 (C) 的第 15 个字符。
我尝试使用如下所示的 fread 函数来处理具有上述字母行的测试文件。参数为 start=1,end=90,生成的文件如下所示:
TGTTCCAGGCTGTCAGATGCTAACCTGGGG
TCACTGGGGGTGTGCGTGCTGCTCCAGCCT
GTTCCAGGATATCAGATGCTCACCTGGG™eRV
每次运行最后都会给出随机字符。
代码:
FILE* fp;
fp=fopen(filename, "r");
if (fp==NULL) puts("Failed to open file");
int start=1, end=90;
char string[end-start+2]; //characters from start to end = end-start+1
fseek(fp, start-1, SEEK_SET);
fread(exon,1, end-start+1, fp);
FILE* tp;
tp=fopen("exon", "w");
if (tp==NULL) puts("Failed to make tmp file");
fprintf(tp, "%s\n", string);
fclose(tp);
我不明白 fread 如何处理 \n 字符,因此我尝试将其替换为以下内容:
int i=0;
char ch;
while (!feof(fp))
{
ch=fgetc(fp);
if (ch != '\n')
{
string[i]=ch;
i++;
if (i==end-start) break;
}
}
string[end-start+1]='\0';
它创建了以下文件: TGTTCCAGGCTGTCAGATGCTAACCTGGGGTCACTGGGGGTGTGCGTGCTGCTCCAGCCTGTTCCAGGATATCAGATGCTCACCTGGGGô
(没有任何换行符,我不介意)。 每次运行时,我都会得到一个不同的随机字符,而不是“G”。
我做错了什么?有没有办法用 fread 或其他功能来完成它?
提前谢谢你。
【问题讨论】:
-
您必须考虑每行 31 个字符(30 个字母后跟
\n),或者甚至可能每行 32 个字符(30 个字母后跟\r\n)。这意味着您可能希望首先检查输入文件的格式。不管怎样,最好使用fseek然后fread。 -
FWIW,
fread根本不关心 EOL 字符。 -
While is while (!feof(fp)) always wrong。
fread不“特别”处理换行符,它只是一个字符。它还返回读取字符的数量,并且结果数据不是以空结尾的。 -
我认为这里有两个问题:(1)您没有考虑到每一行都以换行符结尾,换行符是一个字符。因此,要读取 2 行,您需要读取 30 + 1 + 30 个字符 = 61 个字符,而不是 60 个字符。您可能还想去掉换行符,并在每 30 个字符后添加自己的回行。并且 (2) 您没有在缓冲区的末尾添加空字符,因此当您尝试将其打印为字符串时,它会一直越过末尾,直到它碰巧在内存中遇到一个随机的零字节。跨度>
-
在您自己的循环中使用
fgetc在字符串末尾添加空值,但我认为您的索引已关闭——您应该在@ 时将其添加到i的位置987654334@.
标签: c