sscanf函数改变另一个字符串的内容(sscanf function changes the co

2019-09-03 18:53发布

我有问题读取与字符串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);
 }

Answer 1:

该字符串begin是不是大到足以容纳四个字符sscanf会读取 \0终结。 如果\0被写入到atm (取决于字符串是在存储器中何处), atm将被修改。 从sscanf的手册页 ,关于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;
}

这将产生输出:

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

我打印指针的值要弄清楚它会采取一个字符串有多大溢入atm 。 由于(我的机器上) atom开始于begin+16 ,读16个字符到begin把一个空终止在begin+16 ,这是第一个字符atm ,所以现在atm长度为0。



文章来源: sscanf function changes the content of another string