打印文件中所有字符串的k-mer [关闭]

问题描述 投票:0回答:1

我有一个包含字符串列表的文件。我尝试生成这些的所有k-mer。这是我的代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char* substr(const char *string, size_t start, size_t end) {

  const char *char_start = &string[start];
  const char *char_end = &string[end];

  char *substring = (char *) calloc(1, char_end - char_start + 1);
  memcpy(substring, char_start, char_end - char_start + 1);

  return substring;
}

int main(void) {
  FILE *file;
  file = fopen("out/clean_read_1.txt", "r");
  if (file == NULL) {
    perror("File not found!\n");
    exit(0);
  } 

  char *line = NULL;
  size_t i, len = 0, k = 5;
  ssize_t read;

  while ( (read = getline(&line, &len, file)) != -1 ) {
    for ( i = 0; i < strlen(line) - k; i++ )
      printf("%s\n", substr(line, i, i + k - 1));
  }

  printf("\n");

  fclose(file);

  return 0;
}

这是文件:

ACCAG
CAGTGAA
TGAACGGTA

我不明白为什么代码不生成最后一个k-mer。

预期的正确输出:

ACCAG
CAGTG
AGTGA
GTGAA
TGAAC
GAACG
AACGG
ACGGT
CGGTA

我的代码输出不正确:

ACCAG
CAGTG
AGTGA
GTGAA
TGAAC
GAACG
AACGG
ACGGT
c substring
1个回答
1
投票

我注意到除了最后一行之外,你文件中的每一行都以'\n'结尾。由于getline()也将\n写入line(当它在文件中找到时),那么strlen(line)将总是比该行中可见字符的数量多一个,除了使用最后一行时,因为它不包含'\n'

例如,当您使用文件中的倒数第二行时,line将包含"CAGTGAA\n\0"。不计算终止'\0',那些是7字母字符+ '\n'字符。共有8个将是strlen(line)将返回的。因此strlen(line) - k将等于3,导致for循环循环3次。

但是当你使用文件的最后一行时,line将包含"TGAACGGTA\0"。不计算终止'\0',那些是9字母字符但没有'\n'字符所以strlen(line)将只返回9.因此strlen(line) - k将等于4导致for循环仅循环4次而不是5次导致第5 k- mer没有被生成。

您需要做的是以下之一:

A)在文件末尾添加一个空行,以便当前最后一行也以'\n'结尾。

或:B)更改for循环:

  while ( (read = getline(&line, &len, stdin)) != -1 ) {
    for ( i = 0; line[i+k-1] != '\n' && line[i+k-1] != '\0'; i++ )

或者:C)当'\n'位于行尾时使用终止'\0'时覆盖for,这样行只包含您想要使用的字母字符。然后更改getline()循环中的条件,以考虑这些行现在比以前短一个字符。 (注意,由于'\0'返回写入的字符数,不计算read,并将其存储在 while ( (read = getline(&line, &len, stdin)) != -1 ) { if (line[read - 1] == '\n') line[--read] = '\0'; for ( i = 0; i <= read - k; i++ ) 中,因此无需一次又一次地重新计算字符串的长度):

substring

您的代码至少还有一个问题。你每次调用substr()时都会为line分配空间,但你永远不会释放它,导致内存泄漏(严格来说你也应该释放qazxswpoi)。

© www.soinside.com 2019 - 2024. All rights reserved.