memcpy関数とmemmove関数は、メモリ領域のデータを指定された長さだけコピーします。memcpy関数とmemmove関数の相違は、memcpy関数はコピー元の領域とコピー先の領域が重なってはいけないのに対して、memmove関数は重なっていてもよいということです。
#include <string.h>
void *memcpy(void *dest, const void *src, size_t n);
void *memmove(void *dest, const void *src, size_t n);
*destはコピー先の先頭アドレスを指定します。
*srcはコピー元の先頭アドレスを指定します。
nはコピーする長さをバイト単位で指定します。
戻り値として、第1引数*destのアドレスを返します。
次の例題プログラムは、ファイル中の’&’、'<‘、’>’、’\’記号を、それぞれ’&’、’<’、’>’、’\’に置換して、表示します。
プログラム 例
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SIZE 1024
int main(int argc, char *argv[])
{
FILE *fp;
char buff[SIZE];
char *buff_ptr;
char key[] = '&<>\\'; /* 置換対象文字 */
char *cnv_char[] = {'&', /* 置換文字 & */
'<', /* < */
'>', /* > */
'\'}; /* \ */
int key_index;
if (argc != 2) {
fprintf(stderr, '実行時引数が不当です\n');
exit(EXIT_FAILURE);
}
if ((fp = fopen(argv[1], 'r')) == NULL) {
fprintf(stderr, '%sのオープンができませんでした\n', argv[1]);
exit(EXIT_FAILURE);
}
while(fgets(buff, SIZE, fp) != NULL) {
/* 置換対象文字数分だけ、繰り返す */
for (key_index = 0; key_index < strlen(key); ++key_index) {
buff_ptr = buff;
/* 入力した行の最後まで */
while (*buff_ptr != '\0') {
/* 置換対象文字のチェック */
if (*buff_ptr == key[key_index]) {
/* 置換文字を挿入できる分だけ文字列をずらす */
memmove(buff_ptr + strlen(cnv_char[key_index]),
buff_ptr + 1, strlen(buff_ptr));
/* 置換文字を挿入 */
memcpy(buff_ptr, cnv_char[key_index],
strlen(cnv_char[key_index]));
buff_ptr += strlen(cnv_char[key_index]);
}
else {
++buff_ptr;
}
}
}
printf('%s', buff);
}
fclose(fp);
return EXIT_SUCCESS;
}
例の実行結果
$ cat temp.txt
#include <stdio.h>
int main()
{
printf('Hello World!!.\n');
return 0;
}
$
$ ./memcpy.exe temp.txt
#include <stdio.h>
int main()
{
printf('Hello World!!.\n');
return 0;
}
$