2012-04-06 5 views
0

У меня проблема с некоторыми строками, созданными программой выравнивания последовательностей (это проект биоинформатики). Я пытаюсь добавить дополнительные функции к существующей программе на C, которая анализирует файлы выравнивания, но я столкнулся с некоторыми проблемами с разбором строки «неправильного соответствия», создаваемой программой. Чтобы добавить некоторый контекст, вот пример строки выравнивания:

example = "28G11AC10T32";

Вот как интерпретировать строку: первые 28 оснований соответствуют последовательности, тогда есть несоответствие «G» (29-я базовая сумма), следующее соответствие из 11 базиса (40-я базовая сумма), несоответствие «А» (41-я базовая сумма), несоответствие «C» (42-я базовая сумма) и т. Д.

Мне нужно найти базовое положение, где есть несоответствия (т. Е. Строка имеет символ вместо цифр) и сохранить это в массив int, чтобы я мог посмотреть это в более поздней подпрограмме.

Так вот, где мой вопрос вступает в игру. Я написал подпрограмму, которую я «подумал» мог бы разобрать, но я получаю очень странный артефакт с выхода. ПРИМЕЧАНИЕ: пожалуйста, простите мой ужасный и захламленный код! Я вообще не программист на C, и мое обучение не в информатике!

C: parse char массив цифр, разделенных символами, и превращает цифры в целые числа

int errorPosition(char *mis_match, int *positions){ 
    int i = 0; //iterator for loop 
    int pi = 0; //position array iterator 
    int in = 0; //makeshift boolean to tell if values are inside the pre array 
    int con = 0; //temporary holder for values converted from the pre array 
    char pre[5]; //this array will hold the digit values that will be converted to ints 
    pre[0] = '\0'; 
    for (i = 0; i < strlen(mis_match); i++){ 
     if(isalpha(mis_match[i]) && in == 1){ 
      con += atoi(pre); // this is the part where I get an artifact (see below) 
      positions[pi] = con; 
      con++; 
      pi++; 
      in = 0; 
      memset(&pre[0], 0, sizeof(pre)); 
      pri = 0; 
     }else if(isalpha(mis_match[i]) && in == 0){ 
      positions[pi] = con; 
      con++; 
      pi++; 
     }else if(isdigit(mis_match[i])){ 
      pre[pri] = mis_match[i]; 
      pri++; 
      in = 1; 
     } 
    } 
    if(pri > 0){ 
     con += atoi(pre); 
     positions[pi] = con; 
     pi++; 
    } 

} 

Итак, мой вопрос заключается в том, что, когда я достигаю сегмент, который я комментировал выше («это где я получаю ошибку»), моя «до» строка содержит цифры раз 10. Для например, используя приведенную выше строку примера, в первый раз, когда цикл достигнет этой области, я ожидал бы, что pre будет содержать «28», но вместо этого он содержит «280»! Когда я использую atoi для преобразования строки, это, следовательно, в десять раз выше, чем я ожидаю.
Есть ли что-то, что у меня отсутствует, или какое-то соглашение с символом в C, о котором я не знаю здесь? Заранее благодарю за ваши ответы.

ответ

0

Это может быть не единственная проблема, но вы не обнуляете нулевую строку, которую вы передаете atoi. Символ '0' в третьей позиции 280 может быть мусором, потому что вы никогда не писали в эту позицию массива.

Чтобы решить эту проблему, вы должны добавить эту строку перед вызовом atoi:

pre[pri] = '\0'; 
+0

Gah! Простейший материал, не так ли? Большое спасибо за Ваш ответ! Теперь ints верны и программа работает! – user1317512

0

Следующий код будет извлечь (и печать) числовые & нецифровых части вашей строки; вы можете приспособить его, чтобы делать то, что вам нужно, с этими частями.

char* example = "28G11AC10T32"; 
int pos = 0; 
int value = 0; 
while (1) { 
    if (!isdigit(example[pos])) { 
     if (value > 0) 
      printf("Number = %d\n", value); 
     value = 0; 
     if (example[pos]==0) 
      break; 
     else 
      printf("Char = %c\n", example[pos]); 
    } else { 
     value = value * 10 + example[pos]-'0'; 
    } 
    pos++; 
} 
+0

Более элегантный, чем мое любительское решение. И тебе спасибо! – user1317512