sprintf、strcpyおよびmemcpy関数
4306 ワード
1、sprintfとsnprintf
機能:フォーマットされたデータを文字列バッファインパラメータ:format、出力文字列のフォーマットリスト、例えば%d、%s、%cなどのインパラメータ:formatに対応する不定パラメータリストに書き込み、printfと同様にアウトパラメータ:buffer、グリッド化後の文字列戻り値を格納するための記憶空間を指す:bufferに書き込まれた文字数を返し、エラーが発生したら-1を返す
出力分析:bufferに出力されたコンテンツの長さが10バイトを超えない場合、sprintfの操作はリスクがありません.10バイトを超えるとbufferストレージ空間がオーバーフローし、ストレージ位置から分析するとbuffer空間はスタック空間であり、自身の10バイト以外の空間は他のスタック変数のストレージ空間であり、sprintfが10バイト外の他の空間も操作すると、他のスタック変数の内容を破壊する可能性があり、致命的である可能性がある
機能:長さ制限があり、フォーマットされたデータをある文字列バッファに書き込む:format、出力文字列のフォーマットリスト、例えば「%s%d%c」などのパラメータ:[argument]、formatに対応する不定パラメータリスト、printfの不定パラメータに類似するパラメータ:size、bufferが記憶空間の大きさを指すパラメータ:buffer、記憶空間を指すことを示す.フォーマット後の文字列の戻り値を格納:bufferに書き込む文字数を返し、エラーは-1を返す.bufferまたはformatが空のポインタであり、エラーなく続行すると、関数は-1を返し、errnoはEINVALに設定されます.
出力解析:フォーマットされた文字列の長さ=sizeの場合、(size-1)文字列をbufferにコピーし、その後に文字列の終端記号'0'を追加し、書き込みたい文字列の長さを返します.
結論:snprintfはsprintfのセキュリティバージョンです
1、strcpyfとstrncpy
機能:パラメータsrc文字列をパラメータdestが指すアドレスにコピーすると、dest文字列に終了子'0'が自動的に補完されます.戻り値:destの文字列の開始アドレスを返します.説明:パラメータdestが示すメモリ領域が十分でない場合、バッファオーバーフローのエラーが発生する可能性があります(sprintfと同じ).
出力解析:strcpyはコピー時に終了子'0'に遭遇するとコピーを停止し、dstにコピーした後、コピーした文字列の後ろに自動的に終了子'0'を補うので、出力の結果はabcde
関数の説明:strncpy()は文字列srcの最初のn文字を文字列destにコピーします.戻り値:戻り文字列dest注意:strncpy()はstrcpyのようにdestに終了文字を追加しませんが、終了文字をコピーすることができます.終了文字の後の文字はコピーできません.srcとdestが指すメモリ領域は重複できません.destは十分な空の間にn文字を配置する必要があります.
出力分析:n 1はstrlen(src 1)+1より小さく、'0'は追加されません.n 2はstrlen(src 2)+1に等しく、src 2の末尾の'0'をdest 2 n 3にコピーできるのはstrlen(src 3)+1より大きく、ループコピーstr 3 src 4に'0'が現れ、その後の内容はコピーされない
3、memcpy
機能:srcがアドレスを先頭とする連続nバイトのデータをdestがアドレスを先頭とする空間内の戻り値にコピーする:destを指すポインタを返す注意:srcとdestが指すメモリ領域が重なることができない;strcpyと比較するとmemcpyはエンドマークに遭遇してコピーを停止するのではなく、必ずnバイトをコピーします
int sprintf(char *buffer, const char *format, [argument] ... );
機能:フォーマットされたデータを文字列バッファインパラメータ:format、出力文字列のフォーマットリスト、例えば%d、%s、%cなどのインパラメータ:formatに対応する不定パラメータリストに書き込み、printfと同様にアウトパラメータ:buffer、グリッド化後の文字列戻り値を格納するための記憶空間を指す:bufferに書き込まれた文字数を返し、エラーが発生したら-1を返す
//sprintf
#include
#include
int main()
{
char buffer[10];
const int a = 12345;
const char *b = "102938465839202";
sprintf(buffer, "%d", a); // a int , buffer
sprintf(buffer, "%d+%s", a, b); // a b buffer
return 0;
}
出力分析:bufferに出力されたコンテンツの長さが10バイトを超えない場合、sprintfの操作はリスクがありません.10バイトを超えるとbufferストレージ空間がオーバーフローし、ストレージ位置から分析するとbuffer空間はスタック空間であり、自身の10バイト以外の空間は他のスタック変数のストレージ空間であり、sprintfが10バイト外の他の空間も操作すると、他のスタック変数の内容を破壊する可能性があり、致命的である可能性がある
int snprintf(char *buffer, size_t size, const char *format, [argument] ... );
機能:長さ制限があり、フォーマットされたデータをある文字列バッファに書き込む:format、出力文字列のフォーマットリスト、例えば「%s%d%c」などのパラメータ:[argument]、formatに対応する不定パラメータリスト、printfの不定パラメータに類似するパラメータ:size、bufferが記憶空間の大きさを指すパラメータ:buffer、記憶空間を指すことを示す.フォーマット後の文字列の戻り値を格納:bufferに書き込む文字数を返し、エラーは-1を返す.bufferまたはformatが空のポインタであり、エラーなく続行すると、関数は-1を返し、errnoはEINVALに設定されます.
//snprintf
#include
#include
int main()
{
char buffer[10];
const int a = 12345;
const char *b = "102938465839202";
snprintf(buffer, sizeof(buffer), "%d", a); // a int , buffer
snprintf(buffer, sizeof(buffer), "%d+%s", a, b); // a b buffer
return 0;
}
出力解析:フォーマットされた文字列の長さ
結論:snprintfはsprintfのセキュリティバージョンです
1、strcpyfとstrncpy
char *strcpy(char *dest, const char *src);
機能:パラメータsrc文字列をパラメータdestが指すアドレスにコピーすると、dest文字列に終了子'0'が自動的に補完されます.戻り値:destの文字列の開始アドレスを返します.説明:パラメータdestが示すメモリ領域が十分でない場合、バッファオーバーフローのエラーが発生する可能性があります(sprintfと同じ).
//strcpy
#include
#include
int main()
{
char src[] = "abcde\0jjih";
char dst[] = "amjihgknsnsn";
strcpy(dst, src);
printf("%s
", dst);
return 0;
}
出力解析:strcpyはコピー時に終了子'0'に遭遇するとコピーを停止し、dstにコピーした後、コピーした文字列の後ろに自動的に終了子'0'を補うので、出力の結果はabcde
char *strncpy(char *dest, const char * src, size_t n);
関数の説明:strncpy()は文字列srcの最初のn文字を文字列destにコピーします.戻り値:戻り文字列dest注意:strncpy()はstrcpyのようにdestに終了文字を追加しませんが、終了文字をコピーすることができます.終了文字の後の文字はコピーできません.srcとdestが指すメモリ領域は重複できません.destは十分な空の間にn文字を配置する必要があります.
#include
#include
int main()
{
char dest1[20];
char src1[] = "abc";
int n1 = 3;
char dest2[20] = "***************";
char src2[] = "abcxyz";
int n2 = strlen(src2)+1;
char dest3[100] = "www.baidu.com";
char src3[6] = "abcxyz"; //
int n3 = 20;
char dest4[100] = "www.google.com";
char src4[] = "abc\0defghijk";
int n4 = strlen(src3);
strncpy(dest1, src1, n1); //
strncpy(dest2, src2, n2);
strncpy(dest3, src3, n3);
strncpy(dest4, src4, n4);
printf("dest1 = %s
", dest1);
printf("dest2 = %s, dest2[15] = %c", dest2, dest2[10]);
printf("dest3 = %s
", dest3);
printf("dest4 = %s
, dest4[6] = %d, dest4[20] = %d, dest4[90] = %d
", dest4, dest4[6], dest4[20], dest4[90]);
return 0;
}
出力分析:n 1はstrlen(src 1)+1より小さく、'0'は追加されません.n 2はstrlen(src 2)+1に等しく、src 2の末尾の'0'をdest 2 n 3にコピーできるのはstrlen(src 3)+1より大きく、ループコピーstr 3 src 4に'0'が現れ、その後の内容はコピーされない
3、memcpy
void memcpy(void *dest, const void *src, size_t n);
機能:srcがアドレスを先頭とする連続nバイトのデータをdestがアドレスを先頭とする空間内の戻り値にコピーする:destを指すポインタを返す注意:srcとdestが指すメモリ領域が重なることができない;strcpyと比較するとmemcpyはエンドマークに遭遇してコピーを停止するのではなく、必ずnバイトをコピーします