C 文字列操作 新しいページはコチラ
提供: yonewiki
(→文字列区切り文字分割) |
(→文字列区切り文字分割) |
||
767行: | 767行: | ||
_locale_t locale; | _locale_t locale; | ||
locale = _create_locale(LC_ALL, "Japanese"); | locale = _create_locale(LC_ALL, "Japanese"); | ||
− | + | ||
int iCmpComma=0; | int iCmpComma=0; | ||
int iCmpYen=0; | int iCmpYen=0; | ||
int iCmpSlash=0; | int iCmpSlash=0; | ||
int iChartCommaCnt=0; | int iChartCommaCnt=0; | ||
− | + | ||
− | TCHAR *cStr0 = _T("Sweet Refrain/Perfume,雨のち晴レルヤ/ゆず,東京デスティニー/ポルノグラフィティ,\\熱愛発覚中/椎名林檎と中田ヤスタカ(CAPSULE),STORY OF MY LIFE/ONE DIRECTION,THE SEVEN SEAS/THE BAWDIES,手紙/ナオト・インティライミ,SLY/RIP SLYME,閃光 | + | TCHAR *cStr0 = _T("Sweet Refrain/Perfume,雨のち晴レルヤ/ゆず,東京デスティニー/ポルノグラフィティ,\\熱愛発覚中/椎名林檎と中田ヤスタカ(CAPSULE),STORY OF MY LIFE/ONE DIRECTION,THE SEVEN SEAS/THE BAWDIES,手紙/ナオト・インティライミ,SLY/RIP SLYME,閃光 feat10-FEET/東京スカパラダイスオーケストラ,風は西から/奥田民生,DIAMOND SKIN/GLAY,SO RIGHT/三代目 J Soul Brothers from EXILE TRIBE,White Winter Love。/ハジ→,APPLAUSE/LADY GAGA,ピタカゲ from「COUP D'ETAT[+ONE OF A KIND&HEARTBREAKER]」/G-DRAGON (from BIGBANG),LEMON/The Birthday,もったいないとらんど/きゃりーぱみゅぱみゅ,僕らの物語/GReeeeN,Lily/Dragon Ash,START IT AGAIN/AK-69,Very Merry Xmas/東方神起,SURVIVAL/EMINEM,ウォーリーヒーロー/KANA-BOON,あなたへ/エレファントカシマシ,キラーボール/ゲスの極み乙女。,Babies are popstars/松任谷由実,ROCK N ROLL(日本語字幕入り)/AVRIL LAVIGNE,HOT SHOT/GENERATIONS from EXILE TRIBE,守ってあげたい/JUJU,3 2 1/SHINee,Always/斉藤和義,ファンファーレがきこえる/Base Ball Bear,X'masラブストーリー。/ソナーポケット,Missing/androp,ラストバージン/RADWIMPS,エデン(lyric ver)/Aqua Timez,クルクル/e-girls,WHO'S NEXT/SiM,Time goes by/URATA NAOYA,Bi-Li-Li Emotion/Superfly,One day/TOKYO No1 SOUL SET,粉雪/BENI,FEEVEER/MO'SOME TONEBENDER,No525300887039/supercell,Hello\\,999/N'夙川BOYS,Every Hero/kaho,黒猫?Adult Black Cat?/Acid Black Cherry,指でキスしよう/東京カランコロン,m@u/後藤まりこ,海と花束/きのこ帝国"); |
TCHAR *pcStr0 = new TCHAR[(_tcslen(cStr0)) + 1]; | TCHAR *pcStr0 = new TCHAR[(_tcslen(cStr0)) + 1]; | ||
TCHAR *pcStr1 = new TCHAR[(_tcslen(cStr0)) + 1]; | TCHAR *pcStr1 = new TCHAR[(_tcslen(cStr0)) + 1]; | ||
792行: | 792行: | ||
} | } | ||
} | } | ||
− | TCHAR ***ppcStrChart = new TCHAR**[iChartCommaCnt]; | + | TCHAR ***ppcStrChart = new TCHAR**[iChartCommaCnt + 1]; |
− | TCHAR **ppcStrChartTmp = new TCHAR*[iChartCommaCnt]; | + | TCHAR **ppcStrChartTmp = new TCHAR*[iChartCommaCnt + 1]; |
− | for(int i = 0; i < | + | for(int i = 0; i < iChartCommaCnt + 1;i++){ |
− | *(ppcStrChart + i) = new TCHAR*[ | + | *(ppcStrChart + i) = new TCHAR*[2];//曲名とアーチスト名の2要素固定 |
} | } | ||
− | + | ||
TCHAR *next_token1 = NULL; | TCHAR *next_token1 = NULL; | ||
TCHAR *next_token2 = NULL; | TCHAR *next_token2 = NULL; | ||
− | + | ||
_tcsncpy_s(pcStr0, _tcslen(cStr0) + 1,cStr0, _tcslen(cStr0) + 1);//ココ! | _tcsncpy_s(pcStr0, _tcslen(cStr0) + 1,cStr0, _tcslen(cStr0) + 1);//ココ! | ||
pcStr1 = _tcstok_s(pcStr0,_T(","), &next_token1);//establish 1回目の呼び出し | pcStr1 = _tcstok_s(pcStr0,_T(","), &next_token1);//establish 1回目の呼び出し | ||
{ | { | ||
− | + | ||
int i = 0; | int i = 0; | ||
bool bStopIncriment = false; | bool bStopIncriment = false; | ||
bool bStopIncriment2 = false; | bool bStopIncriment2 = false; | ||
− | while(pcStr1 != NULL && i < | + | while(pcStr1 != NULL && i < (iChartCommaCnt + 1)){ |
− | + | ||
if (bStopIncriment)//区切り文字の前に\が見つかった場合はiを加算しない。 | if (bStopIncriment)//区切り文字の前に\が見つかった場合はiを加算しない。 | ||
{ | { | ||
823行: | 823行: | ||
iCmpYen = _tcsncmp(&pcStr1[_tcslen(pcStr1)-1],tcharYen,1);//お次の区切り文字は,区切りにしたpcStr1の最後の文字は\ではなかったか確認? | iCmpYen = _tcsncmp(&pcStr1[_tcslen(pcStr1)-1],tcharYen,1);//お次の区切り文字は,区切りにしたpcStr1の最後の文字は\ではなかったか確認? | ||
if(iCmpYen != 0){ | if(iCmpYen != 0){ | ||
− | + | ||
//\以外の通常処理 | //\以外の通常処理 | ||
if(!bStopIncriment){ | if(!bStopIncriment){ | ||
832行: | 832行: | ||
_tcsncpy_s(pcStrTmp2,_tcslen(ppcStrChartTmp[i]) + 1,ppcStrChartTmp[i],_tcslen(ppcStrChartTmp[i]) + 1);//正式な区切り文字なので、区切りまでをコピーして格納。i番目の処理は終了。 | _tcsncpy_s(pcStrTmp2,_tcslen(ppcStrChartTmp[i]) + 1,ppcStrChartTmp[i],_tcslen(ppcStrChartTmp[i]) + 1);//正式な区切り文字なので、区切りまでをコピーして格納。i番目の処理は終了。 | ||
ppcStrChart[i][0] = new TCHAR[_tcslen(pcStrTmp2) + 1]; | ppcStrChart[i][0] = new TCHAR[_tcslen(pcStrTmp2) + 1]; | ||
− | + | ||
//完全な入れ子状態。, 区切り処理を / 区切り処理に変えただけ。関数化すればスッキリする。けどそんな関数を作るのが目的ではないので、敢えてコレ。***************** | //完全な入れ子状態。, 区切り処理を / 区切り処理に変えただけ。関数化すればスッキリする。けどそんな関数を作るのが目的ではないので、敢えてコレ。***************** | ||
− | + | ||
− | + | ||
pcStr2 = _tcstok_s(pcStrTmp2, _T("/"), &next_token2);//establish 1回目の呼び出し | pcStr2 = _tcstok_s(pcStrTmp2, _T("/"), &next_token2);//establish 1回目の呼び出し | ||
− | + | ||
− | + | ||
while(pcStr2 != NULL){ | while(pcStr2 != NULL){ | ||
if(bStopIncriment2){ | if(bStopIncriment2){ | ||
847行: | 847行: | ||
_tcsncpy_s(ppcStrChart[i][0], _tcslen(pcStrTmp) + _tcslen(pcStr2) + 1 ,pcStrTmp, _tcslen(pcStrTmp));//バックアップ変数と今回の区切り文字を繋ぐ。 | _tcsncpy_s(ppcStrChart[i][0], _tcslen(pcStrTmp) + _tcslen(pcStr2) + 1 ,pcStrTmp, _tcslen(pcStrTmp));//バックアップ変数と今回の区切り文字を繋ぐ。 | ||
_tcsncat_s(ppcStrChart[i][0], _tcslen(pcStrTmp) + _tcslen(pcStr2) + 1 ,pcStr2, _tcslen(pcStr2));//バックアップ変数と今回の区切り文字を繋ぐ。 | _tcsncat_s(ppcStrChart[i][0], _tcslen(pcStrTmp) + _tcslen(pcStr2) + 1 ,pcStr2, _tcslen(pcStr2));//バックアップ変数と今回の区切り文字を繋ぐ。 | ||
− | + | ||
delete[] pcStrTmp;//バックアップ変数は利用終了。解放。 | delete[] pcStrTmp;//バックアップ変数は利用終了。解放。 | ||
} | } | ||
iCmpSlash = _tcsncmp(&pcStr2[_tcslen(pcStr2) - 1],tcharSlash,1); | iCmpSlash = _tcsncmp(&pcStr2[_tcslen(pcStr2) - 1],tcharSlash,1); | ||
− | + | ||
if(iCmpSlash != 0){ | if(iCmpSlash != 0){ | ||
if(!bStopIncriment2){ | if(!bStopIncriment2){ | ||
− | + | ||
ppcStrChart[i][0] = new TCHAR[_tcslen(pcStr2) + 1]; | ppcStrChart[i][0] = new TCHAR[_tcslen(pcStr2) + 1]; | ||
_tcsncpy_s(ppcStrChart[i][0],_tcslen(pcStr2) + 1,pcStr2,_tcslen(pcStr2) + 1);//正式な区切り文字なので、区切りまでをコピーして格納。i 0番目の処理は終了。 | _tcsncpy_s(ppcStrChart[i][0],_tcslen(pcStr2) + 1,pcStr2,_tcslen(pcStr2) + 1);//正式な区切り文字なので、区切りまでをコピーして格納。i 0番目の処理は終了。 | ||
− | + | ||
} | } | ||
bStopIncriment2 = false; | bStopIncriment2 = false; | ||
867行: | 867行: | ||
bStopIncriment2 = true; | bStopIncriment2 = true; | ||
} | } | ||
− | + | ||
− | + | ||
pcStr2 = _tcstok_s(NULL,_T("/"), &next_token2);//2回目以降の呼び出し | pcStr2 = _tcstok_s(NULL,_T("/"), &next_token2);//2回目以降の呼び出し | ||
ppcStrChart[i][1] = new TCHAR[_tcslen(pcStr2) + 1]; | ppcStrChart[i][1] = new TCHAR[_tcslen(pcStr2) + 1]; | ||
874行: | 874行: | ||
pcStr2 = _tcstok_s(NULL,_T("/"), &next_token2);//2回目以降の呼び出し | pcStr2 = _tcstok_s(NULL,_T("/"), &next_token2);//2回目以降の呼び出し | ||
} | } | ||
− | + | ||
//完全な入れ子状態ここまで************************************************************************************************************************************** | //完全な入れ子状態ここまで************************************************************************************************************************************** | ||
i++; | i++; | ||
881行: | 881行: | ||
} | } | ||
else{ | else{ | ||
− | + | ||
//\なら,は区切りではないので、ppcStrChartTmp[i]を再作成して、1文字分短くして、\,→,と扱いtmpへ格納。 | //\なら,は区切りではないので、ppcStrChartTmp[i]を再作成して、1文字分短くして、\,→,と扱いtmpへ格納。 | ||
ppcStrChartTmp[i] = new TCHAR[_tcslen(pcStr1) + 1];//まずは区切り文字までの長さより1文字、短い領域を確保。 | ppcStrChartTmp[i] = new TCHAR[_tcslen(pcStr1) + 1];//まずは区切り文字までの長さより1文字、短い領域を確保。 | ||
888行: | 888行: | ||
bStopIncriment = true; | bStopIncriment = true; | ||
} | } | ||
− | + | ||
pcStr1 = _tcstok_s(NULL,_T(","),&next_token1);//2回目以降の呼び出し | pcStr1 = _tcstok_s(NULL,_T(","),&next_token1);//2回目以降の呼び出し | ||
} | } | ||
} | } | ||
_tprintf(_T("{| style=\"color:black; background-color:#ffffff;\" cellpadding=\"3\" cellspacing=\"0\" border=\"1\"\n")); | _tprintf(_T("{| style=\"color:black; background-color:#ffffff;\" cellpadding=\"3\" cellspacing=\"0\" border=\"1\"\n")); | ||
− | for(int i = 0; i < iChartCommaCnt;i++){ | + | for(int i = 0; i < iChartCommaCnt + 1;i++){ |
_tprintf(_T("|%s\n|%s\n|-\n"),ppcStrChart[i][0],ppcStrChart[i][1]); | _tprintf(_T("|%s\n|%s\n|-\n"),ppcStrChart[i][0],ppcStrChart[i][1]); | ||
} | } | ||
_tprintf(_T("|%s\n|%s\n|}\n"),ppcStrChart[iChartCommaCnt][0],ppcStrChart[iChartCommaCnt][1]); | _tprintf(_T("|%s\n|%s\n|}\n"),ppcStrChart[iChartCommaCnt][0],ppcStrChart[iChartCommaCnt][1]); | ||
− | + | ||
printf("%d\n",iChartCommaCnt); | printf("%d\n",iChartCommaCnt); | ||
− | for(int i = 0;i < | + | for(int i = 0;i < iChartCommaCnt + 1;i++){ |
delete[] *(ppcStrChartTmp + i); | delete[] *(ppcStrChartTmp + i); | ||
} | } | ||
− | for(int i = 0;i < | + | delete[] ppcStrChartTmp; |
− | + | ||
− | + | for(int i = 0;i < iChartCommaCnt + 1 ;i++){ | |
+ | for(int j = 0;j < 2 ;j++){ | ||
+ | delete[] *(*(ppcStrChart + i) + j); | ||
+ | } | ||
} | } | ||
+ | for(int i = 0;i < iChartCommaCnt + 1 ;i++){ | ||
+ | delete[] *(ppcStrChart + i); | ||
+ | } | ||
+ | delete[] ppcStrChart; | ||
delete[] pcStr0; | delete[] pcStr0; | ||
delete[] pcStr1; | delete[] pcStr1; | ||
1,084行: | 1,091行: | ||
ってな具合にしなきゃいけいないはずなんですけど…strtokを使うとゴミが残りやすいのかな?解放できなくなる。生成した直後なら消せるから、やっぱなんかあるなコレ。リファレンス書くつもりがどんどん疑問が増えて課題が増えてるという…無力だな。また時間があるときにでも、原因を調べてみよう。恐るべしstrtok…。しばらくは、OS側にあとかたづけは任せてみる。ごめんなさい。ときどき再起動しとけばいいのかな…(´Д`;) | ってな具合にしなきゃいけいないはずなんですけど…strtokを使うとゴミが残りやすいのかな?解放できなくなる。生成した直後なら消せるから、やっぱなんかあるなコレ。リファレンス書くつもりがどんどん疑問が増えて課題が増えてるという…無力だな。また時間があるときにでも、原因を調べてみよう。恐るべしstrtok…。しばらくは、OS側にあとかたづけは任せてみる。ごめんなさい。ときどき再起動しとけばいいのかな…(´Д`;) | ||
おそらくは、一度生成したものを再作成するかもしれないという作り方に問題があるのかもしれない。文字列の長さが確定してから容量を確保するようなプログラムにするべきなんだろうね。次から気を付ける。って今回のサンプルはなおさないらしい。コイツ。 | おそらくは、一度生成したものを再作成するかもしれないという作り方に問題があるのかもしれない。文字列の長さが確定してから容量を確保するようなプログラムにするべきなんだろうね。次から気を付ける。って今回のサンプルはなおさないらしい。コイツ。 | ||
+ | |||
+ | と悩んでおりましたが、解決しました。サンプルプログラムも更新済みなので、なんのこっちゃわからないと思いますが、配列は使用する領域よりひとつ多くとっておかないとdeleteできなくなるみたいです。文字列の終端にあるであろう\0と同じですね。ヌルポインターになるまで消去するということかもしれません。TOP50のランキングなのでTCHAR ***ppcStrChart = new TCHAR**[iChartCommaCnt];としてiChartCommaCnt=49の大きさ50の配列にしていましたが、TCHAR ***ppcStrChart = new TCHAR**[iChartCommaCnt '''+ 1'''];としたところ、プログラムの最後に記述したdelete[] 関数が動作するようになりました。ふぅ。同じように曲名とアーチスト名ということで*(ppcStrChart + i) = new TCHAR*[1];としていましたが、ここも*(ppcStrChart + i) = new TCHAR*['''2'''];ですね。消すときは、ひとつ少ない値のループ回数になっています。for(int j = 0;j < 2 ;j++)のとおりです。少しすっきりしたけど、なんつうか基本中の基本も知らなかった。いかに動的なメモリの確保をやってこなかったかってことか考えさせられます。プログラムの中でガッツリ確保してました。面倒だもん。でも、ちょっと不思議。それこそなんかゴミが残りそうだけどねぇ。結局また調べなきゃいけないのか(;´・д・)。 | ||
=='''文字列の型変換'''== | =='''文字列の型変換'''== |