C語言筆記-文本處理(1) 善用 asprintf取代sprintf

sprintf應該都不陌生,不過sprintf()使用上世有風險的,它的原型是:

int sprintf(char *str,const char *format,...)

也就是說使用前必須先建立好空間,再用sprintf()將內容填入:

 int temp=10;

 char str[20];

 sprintf(str," %d * %d *= %d",temp,temp,temp*temp);


str輸出來看的結果為:10 * 10 = 100

但如果今天temp為10000,輸出就是:
10000 * 10000 = 100000000
則長度超過20,造成over flow的問題

用snprintf/asprintf取代不安全的sprintf才是最好的


#include <stdio.h>

void get_strings(char const *in){
    char *cmd;
    int len = strlen("strings ") + strlen(in) + 1;  
    cmd=(char*)malloc(len);
    snprintf(cmd, len, "strings %s", in);
    
    printf("cmd:%s\n",cmd);
    free(cmd);
}

用snprintf,需要先確定長度,還需要自己調用malloc
使用asprintf,它會自動調用malloc


void get_strings_(char const *in){
    char *cmd;
    asprintf(&cmd, "strings %s", in);
    
    printf("cmd:%s\n",cmd);
    free(cmd);  

}

---------------------
asprintf跟sprintf很像,區別在於傳入的是字串的位址而不是字串本身,
asprintf()會自動分配空間



int asprintf(char **str,char *fmt,...) __attribute__((format(printf,2,3)));


int asprintf(char **str,char *fmt, ...){

 va_list argp;

 va_start(argp,fmt);

 char one_char[1];

 int len=vsnprintf(one_char,1,fmt,argp);

 printf("len:%d\n",len);

 if(len<1)

 {

  fprintf(stderr,"an encoding error occurred."

          "Setting the input pointer to NULL/\n");

  *str=NULL;

  return len;

 }

 

 va_end(argp);

 

 *str=malloc(len+1);

 if(!str)

 {

  fprintf(stderr,"couldn't allocate %i bytes.\n",len+1);

  return -1;

 }

 va_start(argp,fmt);

 vsnprintf(*str,len+1,fmt,argp);

 va_end(argp); 

 return len;

} 



int main(int argc, char *argv[]) {

 char *s;

 asprintf(&s,"hello,%s","-Reader-");

 printf("%s\n",s);

 

 asprintf(&s,"%c",'\0');

 printf("blank string:[%s]\n",s);

 

 int i=0;

 asprintf(&s,"%i",i++);

 printf("Zero:%s\n",s);

  

 return 0;

}






此文章內容參考"21 century c"一書,在此做筆記
如須刪除請告知 謝謝

留言

這個網誌中的熱門文章

FreeRTOS學習筆記 (二)-任務創建和刪除(xTaskCreate及vTaskDelete)

FreeRTOS學習筆記 (三)-時間管理vTaskDelay()及vTaskDelayUntil()

MCU的硬體基礎知識(2) 電晶體的應用