URLエンコード関数のurlencode_one_textは日本語にしか対応していない模様
コードを汚いですが見てくれるだけでもうれしいです
設計
- 1. 日本語文字列をuchar.hのmbrtoc32を使用してwhileループしながらchar32_t型の配列にしまう
- 2.1 "/'をカウントする, そして"."があれば一にする(カウントしない)
- [lise=2.3] 2.3 2.2で戻した配列が英数字以外はコード内にあるurlencode_one_text関数を使用してURLエンコードをする.urlencode_one_text関数のresult引数に入れた値をstring_concatenation関数で連結する
- 2.4 2.2で戻した配列が英数字であればurlエンコードをしないでstring_concatenation関数で連結する[/lise]
- 3 string_concatenationのx引数に入れた値を戻すようにする
- 4 最後にリフレッシュする
#include <stdio.h> #include <uchar.h> #include <limits.h> #include <stdlib.h> #include <string.h> #include <unistd.h> typedef short bool; // 0 = false , 1 = true int geturlparserfunc(const char*, char*); static void urlencode_one_text(int x, char*); static void string_concatenation(char*,const char*); int main(void) { char pathname[900] = {'\0'}; geturlparserfunc("https://example.com/言語/search?q=C java&browser=none", pathname); printf("パッチ名: %s\n", pathname); } int geturlparserfunc(const char* name, char* httppath) { int bmfunc_rlen = 0; int inputlen = strlen(name) + 1; char32_t inp32b[inputlen]; int arraycount1 = 0, arraycount2 = 0; mbstate_t mbstate = {0}; char temppath[MB_LEN_MAX+1] = {'\0'}; char temp16char[9]; int while_n = 0; int tempint = 0; int slashconunt = 0, colon = 0; while (1){ bmfunc_rlen = mbrtoc32(&inp32b[arraycount1], &name[arraycount2], MB_LEN_MAX, &mbstate); if ( -1== bmfunc_rlen ){ printf("エラーが発生しました\n"); printf("エンコードエラー又はバイト数が足りませんの可能性があります。"); break; } else if ( -2 == bmfunc_rlen ){ printf("エラーが発生しました\n"); printf("マルチバイト文字の可能性があります。"); break; } else if ( -3 == bmfunc_rlen ){ arraycount1 += 1; continue; } else if (0 == bmfunc_rlen ){ break; } else if ( 0 < bmfunc_rlen ){ arraycount1 += 1; arraycount2 += bmfunc_rlen; continue; } } while (arraycount1 > while_n){ while_n++; if (':' == inp32b[while_n] || '/' == inp32b[while_n]){ if ( ':' == inp32b[while_n]){ colon = 1; } if ('/' == inp32b[while_n]){ slashconunt++; if (3 == slashconunt){ continue; } } } // httppath if ( 3 <= slashconunt && 1 == colon) { bmfunc_rlen = c32rtomb(temppath ,inp32b[while_n], &mbstate); if (-1 == bmfunc_rlen){ printf("エラーが発生しました\n"); printf("有効なワイド文字ではありません\n"); printf("エラー size_t サイズ : %zu\n", bmfunc_rlen); break; } tempint = *(int*)temppath; temppath[bmfunc_rlen + 1] = '\0'; if ( 47 >= tempint || 124 <= tempint ){ urlencode_one_text(tempint, temp16char); string_concatenation(httppath, temp16char); } else { string_concatenation(httppath, temppath); } tempint = 0; } } httppath = httppath; *httppath = *httppath; arraycount1 = 0, arraycount2 = 0, slashconunt = 0, colon = 0 , bmfunc_rlen = 0; tempint = 0 , inputlen = 0; temppath[0] = '\0', temp16char[0] = '\0'; return 0; } static void string_concatenation(char* x,const char* y) { int xn = 0, alln = 0, yn = 0; bool truth = 0; while (1){ if (0 == truth){ if ('\0' == x[xn]){ truth = 1; continue; } xn++; alln++; continue; } if (1 == truth){ x[alln] = y[yn]; yn++; if ('\0' == y[yn]) break; } alln++; } x[alln + 1] = '\0'; *x = *x; xn = 0, alln = 0, yn = 0, truth = 0; return; } static void urlencode_one_text(const int x, char* result) // resultには文字配列の10の容量もっつ引数を与える { int remainder = 0, intlen = 9, tempx = 0, tempx2 = 0; int tempn = 0; char temp_conditions[15] = { '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', }; result[9] = '\0'; tempx = x; while (1){ tempn++; intlen--; tempx2 = tempx / 16; remainder = tempx - (16 * tempx2); tempx = tempx2; if (3 == tempn){ result[intlen] = '%'; tempn = 1; intlen--; } result[intlen] = temp_conditions[remainder - 1]; remainder = 0; if (0 >= intlen){ break; } } remainder = 0, intlen = 0, tempx = 0, tempx2 = 0; result = result; *result = *result; return; }
- 2.4 2.2で戻した配列が英数字であればurlエンコードをしないでstring_concatenation関数で連結する[/lise]