Từ 1 tới 7 trên tổng số 7 kết quả

Đề tài: Xin góp ý hoặc giải pháp về Decode Hex và ghi file trên C++ (IBM iseries)

  1. #1
    Ngày gia nhập
    09 2021
    Bài viết
    3

    Post Xin góp ý hoặc giải pháp về Decode Hex và ghi file trên C++ (IBM iseries)

    Em có viết chương trình decode hex và ghi kết quả vào file trên hệ thống IBM iseries nhưng file được tạo ra với dữ liệu bị sai.
    .

    Đoạn mã Hex của em:

    Hex : 004800751EF3006E00680020004E00671ECD00630020004800 E00020004D0079

    Kết quả decode hex trên dencode

    Click vào hình ảnh để lấy hình ảnh lớn

Tên:		5bddeba9180df77b3e89a8001594f7ee3c79dbb6_2_1035x385.png
Lần xem:	6
Size:		31.0 KB
ID:		74138



    Đoạn chương trình của em.
    Code:
    #include <iostream>
    #include <fstream> 
    #include <string>  
    #include <sstream> 
    #include <ios>     
    #include <stdint.h>
    #include <locale>  
    
    using namespace std;
    
    int main()
    {
      //   setlocale(LC_CTYPE, "en_US.UTF-8");
      locale::global(locale(""));
    
        string input="004800751EF3006E00680020004E00671ECD00630020004800E00020004D0079";
       //int *nullptr = NULL;                             
    int len = input.length();   
    
    if(len % 4 != 0) return 1;                       
    int cvtlen = len / 4 + 1;
    
    //buffer
    wchar_t *wbuff = new wchar_t[cvtlen];            
    wchar_t *ptr = wbuff;
    
    wmemset(wbuff,0,cvtlen);    
    
    string name = "file1.bin";
    wofstream outfile (name.c_str());
    
     for(int i=0;i<len;i+=4){ 
         
       string nextbyte = input.substr(i,4);             
       *ptr = (wchar_t)strtol(nextbyte.c_str(),NULL,16);
    
    //write data to file
       outfile<<ptr;
       ptr++;     
       
     }    
     
     outfile.close();
        return 0;
    }
    Đoạn mã của em chạy trên onlinegdb.com/online_c++_compiler# thì nó trả ra file đúng

    Click vào hình ảnh để lấy hình ảnh lớn

Tên:		Capture1.PNG
Lần xem:	4
Size:		17.6 KB
ID:		74139

    Nhưng khi chạy trên IBM iseries thì trả ra file với dữ liệu bị sai.

    Click vào hình ảnh để lấy hình ảnh lớn

Tên:		Capture.jpg
Lần xem:	7
Size:		27.4 KB
ID:		74140

    Data đã ghi được "Hu" nhưng tới "ỳ" thì file không còn ghi nữa.
    (em không biết IBM iseries có hổ trợ Unicode không nữa, nhưng theo trên doc của IBM thì có).

    Có anh nào làm trên IBM iseries thì góp ý hoặc cho em giải pháp khác với ạ

    Em cảm ơn.

  2. #2
    Ngày gia nhập
    01 2008
    Nơi ở
    Rất đông người
    Bài viết
    742

    Mình không có iSeries, tham gia được không?

    Bạn thử dùng một chương trình xem file ở dạng hex xem sao. Total Commander là 1 lựa chọn khả dĩ.

    Chụp màn hình của nó cho mọi người xem. Cần biết chính xác độ dài và nội dung của file. Nội dung hex nhé.
    Đã được chỉnh sửa lần cuối bởi Ada : 26-09-2021 lúc 01:50 PM.
    -...- -.- .. .-.. .-.. - .... . -... . .- ... - .-.-.

  3. #3
    Ngày gia nhập
    02 2014
    Nơi ở
    TP.HCM
    Bài viết
    999

    Trích dẫn Nguyên bản được gửi bởi luanthanh2612 Xem bài viết
    Em có viết chương trình decode hex và ghi kết quả vào file trên hệ thống IBM iseries nhưng file được tạo ra với dữ liệu bị sai.
    .

    Đoạn mã Hex của em:

    Hex : 004800751EF3006E00680020004E00671ECD00630020004800 E00020004D0079

    Kết quả decode hex trên dencode

    Click vào hình ảnh để lấy hình ảnh lớn

Tên:		5bddeba9180df77b3e89a8001594f7ee3c79dbb6_2_1035x385.png
Lần xem:	6
Size:		31.0 KB
ID:		74138



    Đoạn chương trình của em.
    Code:
    #include <iostream>
    #include <fstream> 
    #include <string>  
    #include <sstream> 
    #include <ios>     
    #include <stdint.h>
    #include <locale>  
    
    using namespace std;
    
    int main()
    {
      //   setlocale(LC_CTYPE, "en_US.UTF-8");
      locale::global(locale(""));
    
        string input="004800751EF3006E00680020004E00671ECD00630020004800E00020004D0079";
       //int *nullptr = NULL;                             
    int len = input.length();   
    
    if(len % 4 != 0) return 1;                       
    int cvtlen = len / 4 + 1;
    
    //buffer
    wchar_t *wbuff = new wchar_t[cvtlen];            
    wchar_t *ptr = wbuff;
    
    wmemset(wbuff,0,cvtlen);    
    
    string name = "file1.bin";
    wofstream outfile (name.c_str());
    
     for(int i=0;i<len;i+=4){ 
         
       string nextbyte = input.substr(i,4);             
       *ptr = (wchar_t)strtol(nextbyte.c_str(),NULL,16);
    
    //write data to file
       outfile<<ptr;
       ptr++;     
       
     }    
     
     outfile.close();
        return 0;
    }
    Đoạn mã của em chạy trên onlinegdb.com/online_c++_compiler# thì nó trả ra file đúng

    Click vào hình ảnh để lấy hình ảnh lớn

Tên:		Capture1.PNG
Lần xem:	4
Size:		17.6 KB
ID:		74139

    Nhưng khi chạy trên IBM iseries thì trả ra file với dữ liệu bị sai.

    Click vào hình ảnh để lấy hình ảnh lớn

Tên:		Capture.jpg
Lần xem:	7
Size:		27.4 KB
ID:		74140

    Data đã ghi được "Hu" nhưng tới "ỳ" thì file không còn ghi nữa.
    (em không biết IBM iseries có hổ trợ Unicode không nữa, nhưng theo trên doc của IBM thì có).

    Có anh nào làm trên IBM iseries thì góp ý hoặc cho em giải pháp khác với ạ

    Em cảm ơn.
    Chỉnh sửa vài dòng mã cho bạn, nó thực hiện đúng; khi kết xuất tập tin kết quả sẽ có 2 trường hợp xảy ra.
    1. Nếu chương trình kết xuất có kết xuất Unicode, dữ liệu được xuất đầy đủ : Huỳnh Ngọc Hà My
    2. Nếu chương trình kết xuất không chấp nhận Unicode, dữ liệu xuất sẽ có dạng : Hu...nh Ng...c H.. My

    Về cách viết mã thì bạn đặt các biến hơi lủng củng, nếu mình viết thì khai báo khoảng 3 biến thôi, thân vòng lặp cũng khoảng 2 dòng thôi.

    C++ Code:
    1. //#include <iostream>
    2. #include <fstream>
    3. //#include <string>  
    4. //#include <sstream>
    5. //#include <ios>    
    6. //#include <stdint.h>
    7. //#include <locale>
    8. #include <codecvt>              //________ Thêm khai báo này __________
    9.  
    10. using namespace std;
    11.  
    12. int main()
    13. {
    14.     //   setlocale(LC_CTYPE, "en_US.UTF-8");
    15.     //locale::global(locale(""));
    16.  
    17.     string input = "004800751EF3006E00680020004E00671ECD00630020004800E00020004D0079";
    18.     //int *nullptr = NULL;
    19.     int len = input.length();
    20.  
    21.     if (len % 4 != 0) return 1;
    22.     int cvtlen = len / 4 + 1;
    23.  
    24.     //buffer
    25.     wchar_t *wbuff = new wchar_t[cvtlen];
    26.     wchar_t *ptr = wbuff;
    27.  
    28.     wmemset(wbuff, 0, cvtlen);
    29.     //__________ Thay 2 lệnh này ___________
    30.     //string name = "file1.bin";
    31.     //wofstream outfile(name.c_str());
    32.  
    33.     //__________ Bằng 2 lệnh sau ___________
    34.     wofstream outfile("file1.bin");
    35.     outfile.imbue(locale(locale::classic(), new codecvt_utf8<wchar_t>));
    36.     //_______________ Hết __________________
    37.  
    38.     for (int i = 0;i<len;i += 4) {
    39.  
    40.         string nextbyte = input.substr(i, 4);
    41.         *ptr = (wchar_t)strtol(nextbyte.c_str(), NULL, 16);
    42.  
    43.         //write data to file
    44.         outfile << ptr;
    45.         ptr++;
    46.  
    47.     }
    48.  
    49.     outfile.close();
    50.     return 0;
    51. }
    .
    .
    .

    - - - Nội dung đã được cập nhật ngày 28-09-2021 lúc 08:29 AM - - -

    Mã rút gọn
    C++ Code:
    1. #include <fstream>
    2. #include <codecvt>
    3. using namespace std;
    4.  
    5. int main()
    6. {
    7.     char input[] = "004800751EF3006E00680020004E00671ECD00630020004800E00020004D0079";
    8.     char buff[] = { 0,0,0,0,0 };
    9.  
    10.     if (strlen(input) % 4)
    11.         return 1;
    12.  
    13.     wofstream outfile("file1.bin");
    14.     outfile.imbue(locale(locale::classic(), new codecvt_utf8<wchar_t>));
    15.  
    16.     for (int i = 0, length = (int)strlen(input); i < length; i += 4)
    17.     {
    18.         memcpy(buff, &input[i], 4);
    19.         outfile << (wchar_t)strtol(buff, NULL, 16);
    20.     }
    21.  
    22.     outfile.close();
    23.     return 0;
    24. }
    .
    .

  4. #4
    Ngày gia nhập
    09 2021
    Bài viết
    3

    Cảm ơn mọi người nhiều ạ.
    Em đã làm được rồi.

  5. #5
    Ngày gia nhập
    01 2008
    Nơi ở
    Rất đông người
    Bài viết
    742

    Trích dẫn Nguyên bản được gửi bởi luanthanh2612 Xem bài viết
    Cảm ơn mọi người nhiều ạ.
    Em đã làm được rồi.
    Vậy à. Bạn có thể chia sẻ thông tin về nguyên nhân và giải pháp của bạn không?

    Cảm ơn.
    -...- -.- .. .-.. .-.. - .... . -... . .- ... - .-.-.

  6. #6
    Ngày gia nhập
    09 2021
    Bài viết
    3

    Mặc định Xin góp ý hoặc giải pháp về Decode Hex và ghi file trên C++ (IBM iseries)

    Trích dẫn Nguyên bản được gửi bởi Ada Xem bài viết
    Vậy à. Bạn có thể chia sẻ thông tin về nguyên nhân và giải pháp của bạn không?

    Cảm ơn.
    Nguyên nhân:

    Trên đoạn code cũ của em có dùng wchar_t như hình bên dưới,
    với cái IDE khác thì em chạy thì tạo ra được file với file UTF-16LE và dữ liệu hoàn toàn đúng,
    Nhưng trên IBM iseries thì ghi ra file UTF-8 nên dữ liệu không chính xác, nên em nghĩ IBM iseries không thể ghi dữ liệu kiểu wchar_t (wchar_t có thể lưu UTF-16) vào file khi có những ký tự có dấu như "ỳ ý ạ...".

    Em cũng không có kinh nghiệm nhiều về C++ và IBM iseries nên em giải thích như vậy có đúng ko ạ.

    Đính kèm 74145

    Giải pháp em vô tình tìm thấy được đoạn code chuyển đổi từ UTF-16 sang UTF-8 trên trang cppdeveloper
    Em thay wchar_t sang uint16_t là mọi thứ đã được giải quyết trên IBM iseries.


    Code:
    std::string convertUTF16toUTF8(const uint16_t* utf16Buf)
    {
        std::string utf8Str = "";
        uint16_t utf16CodePoint = 0;
     
        // convert (refer to https://en.wikipedia.org/wiki/UTF-8)
        for (utf16Buf; *utf16Buf != 0; ++utf16Buf) {
            utf16CodePoint = *utf16Buf;
     
            // 7 bits codepoint
            if (utf16CodePoint <= 0x007f) {
                // using 1 byte: 0xxxxxxx
                utf8Str.append(1, static_cast<char>(utf16CodePoint));
            } 
            // 11 bits codepoint
            else if (utf16CodePoint <= 0x07ff) {
                // using 2 bytes: 110xxxxx 10xxxxxx
                char byte1 = 0xc0 | ((utf16CodePoint >> 6) & 0x1f);
                char byte2 = 0x80 | (utf16CodePoint & 0x3f);
                utf8Str.append(1, byte1);
                utf8Str.append(1, byte2);
            }
            // 16 bits codepoint
            else {
                // using 3 bytes: 1110xxxx 10xxxxxx 10xxxxxx
                char byte1 = 0xe0 | ((utf16CodePoint >> 12) & 0x0f);
                char byte2 = 0x80 | ((utf16CodePoint >> 6) & 0x3f);
                char byte3 = 0x80 | (utf16CodePoint & 0x3f);
                utf8Str.append(1, byte1);
                utf8Str.append(1, byte2);
                utf8Str.append(1, byte3);
            }
        }
     
        return utf8Str;
    }

  7. #7
    Ngày gia nhập
    01 2008
    Nơi ở
    Rất đông người
    Bài viết
    742

    Trích dẫn Nguyên bản được gửi bởi luanthanh2612 Xem bài viết
    Nguyên nhân:

    Trên đoạn code cũ của em có dùng wchar_t như hình bên dưới,
    với cái IDE khác thì em chạy thì tạo ra được file với file UTF-16LE và dữ liệu hoàn toàn đúng,
    Nhưng trên IBM iseries thì ghi ra file UTF-8 nên dữ liệu không chính xác, nên em nghĩ IBM iseries không thể ghi dữ liệu kiểu wchar_t (wchar_t có thể lưu UTF-16) vào file khi có những ký tự có dấu như "ỳ ý ạ...".

    Em cũng không có kinh nghiệm nhiều về C++ và IBM iseries nên em giải thích như vậy có đúng ko ạ.
    Mình không nghĩ thế. Và như post đầu tiên mình đã gửi, trước khi nói đến giải pháp, mình muốn tìm nguyên nhân. Hình chụp của bạn có quá ít thông tin để chỉ ra nguyên nhân.

    char thường có 8 bit. Nhưng wchar_t thì không nhất thiết và thường không có 16 bit. Nên dùng wchar_t không phải là cách tốt nhất để xử lý tiếng Việt. Song, code bạn gửi ban đầu dùng wchar_t nên mình đã muốn cùng bạn đi theo hướng đó đến cùng. Nếu không vì một mục đích thực tiễn trước mắt, ít ra cũng để hiểu rõ iSeries hỗ trợ Unicode ra sao, để giúp cho công việc lâu dài về sau.

    Bạn đã hài lòng về kết quả này thì thôi. Chúc bạn thành công.
    -...- -.- .. .-.. .-.. - .... . -... . .- ... - .-.-.

Quyền hạn của bạn

  • Bạn không thể gửi đề tài mới
  • Bạn không thể gửi bài trả lời
  • Bạn không thể gửi các đính kèm
  • Bạn không thể chỉnh sửa bài viết của bạn