Функция sscanf изменяет содержимое другой строки

У меня проблемы с чтением строкsscanf, Я набросал код, чтобы сосредоточиться на проблеме. Ниже приведена функция во всем коде, которая должна открывать файл и что-то читать. Ноsscanf действует странно. Например, я объявляю строку с именемatm с содержанием'ATOM', Передsscanf печатает эту строку какATOM в то время как после того, как это ноль. В чем может быть проблема? Я предполагаю, что это должно быть проблемой распределения, но я не мог найти это. Я попробовал некоторые предложения на другие темы, такие как замена%s с другими вещами, но это не помогло.

 void Get (struct protein p, int mode, int type) 
 {
   FILE *fd; //input file
   char name[100]="1CMA"; //array for input file name
   char string[600]; //the array where each line of the data file is stored when reading
   char atm[100]="ATOM";
   char begin[4];
   int index1 =0;

   fd = fopen(name, "r"); // open the input file

   if(fd==NULL) {
     printf("Error: can't open file.\n");
     return 1;
   }    

   if( type==0 ) { //pdb file type
     if( mode==0 ) { 
       while( fgets(string, 600, fd)!=NULL ) {
         printf("1 %s\n",atm);
         sscanf (string, "%4s", begin );
         printf("2 %s \n",atm);
       }
     }   
   }
   fclose(fd);
   free(fd);
   free(name);
 }

Ответы на вопрос(1)

Решение Вопроса

begin ISN»достаточно большой, чтобы вместить четыре символа, которыеsscanf буду читатьа также его\0 терминатор. Если\0 написано вatm (в зависимости от того, где находятся строки в памяти),atm будет изменен. Отsscanf manpageоs Директива: s

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

Я смог воспроизвести это поведение на моей машине, хотя точное расположение строк в памяти было немного другим. Однако, печатая адреса строк, легко понять, что именнопроисходит Вот'Это минимальный пример:

#include<stdio.h>

int main() { 
  char begin[2];
  char atm[100]="ATOM";

  printf("begin:    %p\n", begin);
  printf("begin+16: %p\n", begin+16);
  printf("atom:     %p\n", atm);
  printf("1 %s\n",atm);
  sscanf("AAAABBBBCCCCDDDD", "%16s", begin);
  printf("2 %s \n",atm);
  return 0;
}
</stdio.h>

Это производит вывод:

$ ./a.out 
begin:    0x7fffffffe120
begin+16: 0x7fffffffe130
atom:     0x7fffffffe130
1 ATOM
2  

Я напечатал значения указателей, чтобы выяснить, насколько большой строки потребуется для переполненияatm, Так как (на моей машине)atom начинается вbegin+16, читая шестнадцать символов вbegin помещает нулевой терминатор вbegin+16, который является первым персонажемatm, а сейчасatm имеет длину 0.

 Sina16 мая 2013 г., 19:26
Спасибо, что это была действительно проблема, и пост был очень поучительным.
 Joshua Taylor22 мая 2013 г., 16:50
@Sina Есть компиляторы (и плагины компиляторов), которые пытаются обнаружить некоторые переполнения буфера, но у меня нетЯ использовал любой из них. Прости я могуна этом фронте не было бы никакой помощи.
 Sina22 мая 2013 г., 15:46
спасибо, на самом деле у меня было сообщение о matlab: p Обычно я общаюсь в математическом разделе. Последующий вопрос: поскольку я использую tcc-компилятор, трудно отлавливать эти ошибки, особенно когда код становится слишком длинным, я даже видел случаи, когда компилятор также пропускал эти ошибки и даже был убежден записать в четвертую запись трехмерный массив, который занимает дни, чтобы найти. Есть ли какой-нибудь компилятор или отладчик, который вы могли бы посоветовать отлавливать такие ошибки?
 Joshua Taylor16 мая 2013 г., 19:30
@ Сина Рад помочь! Я почти начал ответ с "Поздравляем с успешным вступлением в Buffer Overflow Club, одну из крупнейших ассоциаций профессиональных программистов! ", но иногда юмор нене попадаются в тексте. Это те ошибки, которые очень легко написать и, вероятно, скрываются во многих строках кода. Рад, что мы поймали один сегодня! :)

Ваш ответ на вопрос