strncpyのようで後ろからn文字文コピーする関数

解決


Jack06  2006-01-27 17:12:32  No: 60572  IP: 192.*.*.*

strncpyという関数は

char *strncpy(char* s, char* t, int n); 

文字列tのうち最大n文字を文字列sにコピーし,sを返す.
tがn文字より少ないときにはNULL文字を詰める.

とありますが、後方からn文字コピーする方法はありますでしょうか。
自分で関数を作る必要がありますか?


ABCDEFGHIJK
という文字列の後ろから5文字コピー
結果:GHIJK

VC6.0 コンソールアプリです。

編集 削除
KING・王  2006-01-27 17:36:35  No: 60573  IP: 192.*.*.*

> 後方からn文字コピーする方法はありますでしょうか。
> 自分で関数を作る必要がありますか?

元の文字列ならば、次のようにすればいいだけでは?

strncpy( s, &t[strlen(t)-n], n );

編集 削除
Blue  2006-01-27 17:37:11  No: 60574  IP: 192.*.*.*

> 自分で関数を作る必要がありますか?
標準ではなさそうですね。
ポインタの位置をうまくずらしてstrcpyするしかなさそう。

CString::Rightのソースが参考になるかも。
(といっても、かなり単純ですが。)

「バイト数」ではなく「文字数」となると、(_MBCSのとき)少し工夫が必要です。

編集 削除
Toshi  2006-01-27 17:39:00  No: 60575  IP: 192.*.*.*

#define  strRightCpy(p1,p2,n)  strncpy(p1,p2+(strlen(p2)-n),n)

char  szStr1[64];
char  szStr2[64];
strcpy(szStr1, "abcdefg");
strRightCpy(szStr2, szwStr1, 3);

じゃダメですか?
(strncpyと同じでNULLを付加しませんが)

編集 削除
KING・王  2006-01-27 17:39:03  No: 60576  IP: 192.*.*.*

typo
> 元の文字列ならば、次のようにすればいいだけでは?
元が文字列ならば、次のようにすればいいだけでは?

上記例に関して、strlen(t) >= n の条件が抜けていました。

編集 削除
Blue  2006-01-27 17:39:58  No: 60577  IP: 192.*.*.*

> strncpy( s, &t[strlen(t)-n], n );
これだと、あらかじめsが '\0' で初期化するか、
s[ n ] = '\0';
をいれないとダメですね。
(strncpyは'\0'を入れない)

編集 削除
Blue  2006-01-27 17:46:57  No: 60578  IP: 192.*.*.*

> CString::Rightのソースが参考になるかも。
参考にしてみました。

TCHAR* Right( TCHAR* dest, const TCHAR* src, int count )
{
    int length = _tcslen( src );
    if ( count < 0 )
        count = 0;
    if ( count > length )
        return strcpy( dest, src );

    return strcpy( dest, src + length - count );
}

int _tmain( void )
{
    TCHAR s[ 6 ];

    Right( s, _T( "ABCDEFGHIJK" ), 5 );
    return 0;
}

編集 削除
Blue  2006-01-27 17:50:05  No: 60579  IP: 192.*.*.*

間違えました。
> strcpy
_tcscpy
です。

編集 削除
Jack06  2006-01-27 18:12:11  No: 60580  IP: 192.*.*.*

早い解答をありがとうございます。
CStringは覚えておき、自作関数の参考にしたいと思います。
書いていただいたものも参考にきっちり使えるようにしたいと思います。

KING・王さんならびにToshiさんの書いてくださったコードは

  char    szStr1[64] = {0};
  char    szStr2[64] = {0};

で初期化して使ってみます。
ありがとうございました。

編集 削除
Toshi  2006-01-27 18:28:49  No: 60581  IP: 192.*.*.*

char    szStr1[64] = {0};
char    szStr2[64] = {0};

処理系にもよるとは思いますが、その初期化で strncpy()の後始末は出来ないです。
必ず、右側n文字のコピー後、ヌルターミネートしても良いと言う前提なら、
strncpy(p1,p2+(strlen(p2)-n),n)  じゃなくて
strcpy(p1,p2+(strlen(p2)-n)) にすればいいだけです。
もっとも、2バイトコードやunicode系なんか関係ない世界での話しだとは思ってますが、もし関係するなら他の方のアドバイスはしっかり受け止めて下さい。

編集 削除
Jack06  2006-01-28 16:29:30  No: 60582  IP: 192.*.*.*

char a[0];
char b[0];
    
for(int i = 2; i < 0; i++)
      b[i - 2] = a[i];

でも出来そうですね。

編集 削除