Kỹ thuật C++: Xin hỏi các hàm xử lý xâu trong C,C++ – Trang 3

sprintf(…) thì ko có giới hạn tối đa bao nhiêu ký tự, mình phải ước lượng đảm bảo là mảng ký tự truyền vào có khả năng chứa đủ.

vd khai báo s[10], s có khả năng chứa tối đa 9 ký tự, in sprintf(s, “%d”, num) thì có khả năng khi num > 999,999,999 tức là chuỗi tương ứng có 10 ký tự thì gây lỗi. Gọi snprintf(s, 9, “%d”, num) thì khi in num = 1234567890 nó sẽ bỏ ký tự cuối cùng là 0, chuỗi in vào s là “123456789”, bảo đảm ko gây lỗi.

vd cho thấy cái “lỗi” khi xài sprintf nếu ko cẩn thận:

C++ Code:

Select All | Show/Hide

  1. #include <cstdio>

  2. #include <cstring>

  3.  

  4. int

    main

    (

    )

  5. {

  6.    

    char

    s1

    [

    8

    ]

    =

    “s1”

    ;

  7.    

    char

    s2

    [

    8

    ]

    =

    “s2”

    ;

  8.    

  9.     sprintf

    (

    s2

    >

    s1

    ?

    s1

    :

    s2,

    “%d”

    ,

    12345678

    )

    ;

    //in vào chuỗi nào có địa chỉ bé hơn

  10.     printf

    (

    “s1 = %s

    \n

    “, s1

    )

    ;

  11.     printf

    (

    “s2 = %s

    \n

    “, s2

    )

    ;

  12. }

Code:

s1 = 12345678
s2 =

Code:

['s']['1']['\0'][ ][ ][ ][ ][ ]['s']['2']['\0'][ ][ ][ ][ ][ ]
  ^s1                            ^s2

Code:

['1']['2']['3']['4']['5']['6']['7']['8']['\0']['2']['\0'][ ][ ][ ][ ][ ]
  ^s1                                     ^s2

snprintf(…) là in vào chuỗi tối đa n ký tự. n là số 79 đó. Nếu mảng truyền vào là char s[m] thì n lớn nhất là n = m-1 (1 cho ký tự ‘\0’)sprintf(…) thì ko có giới hạn tối đa bao nhiêu ký tự, mình phải ước lượng đảm bảo là mảng ký tự truyền vào có khả năng chứa đủ.vd khai báo s[10], s có khả năng chứa tối đa 9 ký tự, in sprintf(s, “%d”, num) thì có khả năng khi num > 999,999,999 tức là chuỗi tương ứng có 10 ký tự thì gây lỗi. Gọi snprintf(s, 9, “%d”, num) thì khi in num = 1234567890 nó sẽ bỏ ký tự cuối cùng là 0, chuỗi in vào s là “123456789”, bảo đảm ko gây lỗi.vd cho thấy cái “lỗi” khi xài sprintf nếu ko cẩn thận:output:Đáng lẽ s2 phải in ra là “s2”, nhưng lại ko in ra gì. Nguyên nhân là do s2 nằm liền kề s1:khi in 12345678 vào s1, sprintf in vào “12345678” + 1 ký tự ‘\0’ kết thúc, ký tự này bị chép đè sang s2:nên s2 bây giờ được hiểu là chuỗi trống vì ký tự đầu tiên của nó là ‘\0’