#include <stdio.h>
#include <uchar.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
char32_t in[] = U"http://google.com"; // or "z\u00df\u6c34\U0001F34C"
mbstate_t mbstate = {0};
char rpath[MB_LEN_MAX+5];
char* as;
if (in[0] =='/'){
printf("\n/を発見した\n");
}
size_t bmfunc_rlen = c32rtomb(rpath ,in[0], &mbstate);
if ((size_t)(-1) == bmfunc_rlen){
printf("エラーが発生しました\n");
printf("有効なワイド文字ではありません\n");
printf("エラー size_t サイズ : %zu\n", bmfunc_rlen);
return 0;
}
printf(" ここだよ %s\n", rpath);
strcat(as, rpath);
printf("結合後: %s\n", as);
}
マルチバイトの変換後出力がaが追加される
マルチバイトの変換後出力がaが追加される
何故aが追加されるか分かりません
面倒なことはCGo使おう!
Re: マルチバイトの変換後出力がaが追加される
c32rtomb | Programming Place Plus C言語編 標準ライブラリのリファレンス
不定である未初期化の自動変数の値の参照が発生し、未定義動作になります。
さらに、asも未初期化のままstrcatに渡されているため、未定義動作になります。
の前に を加えると改善するでしょう。
文字列ではないもの(ナル終端されていない文字配列)を文字列を要求するstrcatに渡しているため、注意
あくまで文字の変換なので、末尾に終端文字(U'\0') は付加されない。
不定である未初期化の自動変数の値の参照が発生し、未定義動作になります。
さらに、asも未初期化のままstrcatに渡されているため、未定義動作になります。
の前に を加えると改善するでしょう。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)
Re: マルチバイトの変換後出力がaが追加される
まさかそんなことだったとは地味に悔しいですqみけCAT さんが書きました: ↑3年前c32rtomb | Programming Place Plus C言語編 標準ライブラリのリファレンス注意
あくまで文字の変換なので、末尾に終端文字(U'\0') は付加されない。
一応、動いてくれましたc言語に詳しくないのでバグがまだありそうですが
asを初期化しないでwindowsのコマンドプロンプトから実行するとなぜか上手いこといかないのでasを初期化しました。windowsのPowerShellでは上手いこといくのに
#include <stdio.h>
#include <uchar.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
char32_t in[] = U"ttp://google.com"; // or "z\u00df\u6c34\U0001F34C"
mbstate_t mbstate = {0};
char rpath[MB_LEN_MAX+1];
char* as = '\0';
if (in[0] =='/'){
printf("\n/を発見した\n");
}
size_t bmfunc_rlen = c32rtomb(rpath ,in[0], &mbstate);
if ((size_t)(-1) == bmfunc_rlen){
printf("エラーが発生しました\n");
printf("有効なワイド文字ではありません\n");
printf("エラー size_t サイズ : %zu\n", bmfunc_rlen);
return 0;
}
rpath[(size_t)strlen(rpath)] = '\0';
printf(" ここだよ %s\n", rpath);
printf("a%#x\n", as);
printf("c%#x\n", rpath);
as = malloc((size_t)sizeof(rpath));
strcat(as, rpath);
printf("結合後: %s\n", as);
printf("b%#x", as);
free(as);
}
面倒なことはCGo使おう!
Re: マルチバイトの変換後出力がaが追加される
大量に未定義動作をしていますね。
また、定義があるlimits.hをincludeせずにMB_LEN_MAXを使っているという問題もあります。
また、定義があるlimits.hをincludeせずにMB_LEN_MAXを使っているという問題もあります。
#include <stdio.h>
#include <uchar.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
char32_t in[] = U"ttp://google.com"; // or "z\u00df\u6c34\U0001F34C"
mbstate_t mbstate = {0};
char rpath[MB_LEN_MAX+1];
char* as = '\0';
if (in[0] =='/'){
printf("\n/を発見した\n");
}
size_t bmfunc_rlen = c32rtomb(rpath ,in[0], &mbstate);
if ((size_t)(-1) == bmfunc_rlen){
printf("エラーが発生しました\n");
printf("有効なワイド文字ではありません\n");
printf("エラー size_t サイズ : %zu\n", bmfunc_rlen);
return 0;
}
/*
未定義動作:初期化されていない自動変数の値の使用
strlenは文字列(ナル終端された文字の列)を要求するのに、
ナル終端されていない配列が渡されている。
また、もし初期化されていたとしても、
strlen(rpath)にはもともと'\0'が入っているはずなので、意味のないコードである。
'\0'を書き込む位置はbmfunc_rlenを用いて決めるべき。
*/
rpath[(size_t)strlen(rpath)] = '\0';
printf(" ここだよ %s\n", rpath);
/*
未定義動作:書式とデータのミスマッチ
%xはunsigned int型のデータを要求するが、asはchar*型である。
printfを用いてポインタを出力するには、
出力するポインタをvoid*型にキャストし、書式%pを用いるべきである。
*/
printf("a%#x\n", as);
/*
未定義動作:書式とデータのミスマッチ
%xはunsigned int型のデータを要求するが、rpathはchar*型に変換されて渡される。
printfを用いてポインタを出力するには、
出力するポインタをvoid*型にキャストし、書式%pを用いるべきである。
*/
printf("c%#x\n", rpath);
as = malloc((size_t)sizeof(rpath));
/*
未定義動作:mallocで確保され、初期化されていない領域の値の使用
strcatは文字列(ナル終端された文字の列)を要求するのに、
ナル終端されていない配列が渡されている。
rpathにはきちんと文字列を格納するように修正することを前提として、
この場合、strcatではなくstrcpyを用いるのがよいだろう。
*/
strcat(as, rpath);
printf("結合後: %s\n", as);
/*
未定義動作:書式とデータのミスマッチ
%xはunsigned int型のデータを要求するが、asはchar*型である。
printfを用いてポインタを出力するには、
出力するポインタをvoid*型にキャストし、書式%pを用いるべきである。
*/
printf("b%#x", as);
free(as);
}
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)
Re: マルチバイトの変換後出力がaが追加される
コンパラ君...
'\0'君も確認できたし大丈夫だろう
#define __STDC_WANT_LIB_EXT1__ 1
#include <stdio.h>
#include <string.h>
#include <uchar.h>
#include <limits.h>
#include <stdlib.h>
int geturlparserfunc(const char*, char*, char*);
int main(void)
{
char hostname, pathname;
geturlparserfunc("https://youtube.com", &hostname, &pathname);
printf("ホスト名; %s\n", hostname);
printf("パッチ名: %s\n", pathname);
}
int geturlparserfunc(const char* name, char* rhost, char* rpath)
{
size_t bmfunc_rlen;
int inputlen = strlen(name) + 1;
char input[(int)inputlen];
char32_t inp32b[(int)inputlen + 1];
int arraycount1 = 0, arraycount2 = 0;
mbstate_t mbstate = 0;
char temphost[MB_LEN_MAX+5];
char temppath[MB_LEN_MAX+5];
int slashconunt = 0, colon = 0;
strcpy_s(input, inputlen, (char*)(name));
while (1){
bmfunc_rlen = mbrtoc32(&inp32b[arraycount1], &input[arraycount2], MB_LEN_MAX, &mbstate);
if ( (size_t)(-1) == bmfunc_rlen ){
printf("エラーが発生しました\n");
printf("エンコードエラー又はバイト数が足りませんの可能性があります。");
printf("エラー size_t サイズ : %zu\n", bmfunc_rlen);
break;
} else if ( (size_t)(-2) == bmfunc_rlen ){
printf("エラーが発生しました\n");
printf("マルチバイト文字の可能性があります。");
printf("エラー size_t サイズ : %zu\n", bmfunc_rlen);
break;
} else if ( (size_t)(-3) == bmfunc_rlen ){
arraycount1++;
continue;
} else if (( (size_t)(0) == bmfunc_rlen ) ){
break;
} else if ( (size_t)(0) < bmfunc_rlen ){
arraycount1++;
arraycount2 += (int)(bmfunc_rlen);
}
}
for (size_t n = 0; arraycount1 > n ; n++){
printf("%#x\n", inp32b[n]);
if (inp32b[n] == ':' || inp32b[n] == '/'){
if (inp32b[n] == ':'){
colon = 1;
}
if (inp32b[n] == '/'){
slashconunt+=1;
}
}
if (slashconunt > 3 && colon == 1) {
bmfunc_rlen = c32rtomb(rpath ,inp32b[n], &mbstate);
if ((size_t)(-1) == bmfunc_rlen){
printf("エラーが発生しました\n");
printf("有効なワイド文字ではありません\n");
printf("エラー size_t サイズ : %zu\n", bmfunc_rlen);
break;
}
printf("%s\n", rpath);
}
if (slashconunt == 2 && colon == 1){
// rhost 処理
bmfunc_rlen = c32rtomb(rhost ,inp32b[n], &mbstate);
if ((size_t)(-1) == bmfunc_rlen){
printf("エラーが発生しました\n");
printf("有効なワイド文字ではありません\n");
printf("エラー size_t サイズ : %zu\n", bmfunc_rlen);
break;
}
}
}
printf("temppath:\t %s\n", rhost);
printf("temphost:\t %s\n", rpath);
arraycount1 = 0, arraycount2 = 0, slashconunt = 0, colon = 0 , bmfunc_rlen = 0;
return 0;
}
面倒なことはCGo使おう!