fasta files okunması gereken bir kod yazıyor, bu nedenle kodumun bir kısmı (aşağıda verilmiştir) bir fasta ayrıştırıcısıdır. Tek bir sıra, fasta biçiminde birden çok satıra yayılabildiğinden, dosyadan okunan birden çok satırı tek bir dizeye birleştirmem gerekir. Bunu, her satırı okuduktan sonra string arabelleğini okuyarak, dizinin mevcut uzunluğu ve okunan satırın uzunluğu olarak yeniden yazarak yapıyorum. Başka bir şey yapıyorum. İlk sıra, ancak fasta dosyaları çoklu dizileri içerebilir. Benzer şekilde, iki karakter dizisi (başlık ve gerçek sıra) ile "char *" olan dinamik bir yapı dizim var. Yine, yeni bir başlıkla karşılaştığımda ('>' ile başlayan bir satırla tanıştım), dizilerin sayısını artırıyorum ve sıra listesi arabelleğini yeniden yazarım. Ben neden göremiyorum Beni hayat içinDosyadan okunurken arabelleği genişletmek için realloc kullanma
*** glibc detected *** ./stackoverflow: malloc(): memory corruption: 0x09fd9210 ***
Aborted
ile ikinci sırası için alanı ayrılıyor üzerinde realloc çalışma sırasında parçalama arızası.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <math.h>
#include <errno.h>
//a struture to keep a record of sequences read in from file, and their titles
typedef struct {
char *title;
char *sequence;
} sequence_rec;
//string convenience functions
//checks whether a string consists entirely of white space
int empty(const char *s) {
int i;
i = 0;
while (s[i] != 0) {
if (!isspace(s[i])) return 0;
i++;
}
return 1;
}
//substr allocates and returns a new string which is a substring of s from i to
//j exclusive, where i < j; If i or j are negative they refer to distance from
//the end of the s
char *substr(const char *s, int i, int j) {
char *ret;
if (i < 0) i = strlen(s)-i;
if (j < 0) j = strlen(s)-j;
ret = malloc(j-i+1);
strncpy(ret,s,j-i);
return ret;
}
//strips white space from either end of the string
void strip(char **s) {
int i, j, len;
char *tmp = *s;
len = strlen(*s);
i = 0;
while ((isspace(*(*s+i)))&&(i < len)) {
i++;
}
j = strlen(*s)-1;
while ((isspace(*(*s+j)))&&(j > 0)) {
j--;
}
*s = strndup(*s+i, j-i);
free(tmp);
}
int main(int argc, char**argv) {
sequence_rec *sequences = NULL;
FILE *f = NULL;
char *line = NULL;
size_t linelen;
int rcount;
int numsequences = 0;
f = fopen(argv[1], "r");
if (f == NULL) {
fprintf(stderr, "Error opening %s: %s\n", argv[1], strerror(errno));
return EXIT_FAILURE;
}
rcount = getline(&line, &linelen, f);
while (rcount != -1) {
while (empty(line)) rcount = getline(&line, &linelen, f);
if (line[0] != '>') {
fprintf(stderr,"Sequence input not in valid fasta format\n");
return EXIT_FAILURE;
}
numsequences++;
sequences = realloc(sequences,sizeof(sequence_rec)*numsequences);
sequences[numsequences-1].title = strdup(line+1); strip(&sequences[numsequences-1].title);
rcount = getline(&line, &linelen, f);
sequences[numsequences-1].sequence = malloc(1); sequences[numsequences-1].sequence[0] = 0;
while ((!empty(line))&&(line[0] != '>')) {
strip(&line);
sequences[numsequences-1].sequence = realloc(sequences[numsequences-1].sequence, strlen(sequences[numsequences-1].sequence)+strlen(line)+1);
strcat(sequences[numsequences-1].sequence,line);
rcount = getline(&line, &linelen, f);
}
}
return EXIT_SUCCESS;
}
Alt dizinin rutini hakkındaki tüm yorumlar için teşekkürler. Onu koduma yerleştirdim. Bununla birlikte, negatif indekslerle uğraşmamın yanlış olduğunu da fark ettim. Negatif indeksi eklemem, çıkarmamalıyım. Söylediğim gibi, altstr işlevini kopyaladım, yapıştırılan kodun geri kalanında aramadım. – sirlark
'strip()' de buggy'dir. Sıfır uzunluklu dizelerle kötü şeyler yapar. Böyle dizelerle konuşmuyor gibi görünüyor, ama başka bir yerde kullanıldığında düzeltmek için iyi bir şey olacağını düşünüyorum. –