跳至內容
Astera Technology

中文欄為何把定長格式的下一欄移位?

欄界既按字節訂,就先按字節截好,才各欄解碼。

下載完整個案資料及參考答案 ↓

先核來源與已訂規則

本例名稱佔三個 UTF-8 字節,其後兩字節是數量文字,原內容為「你12」。須在有效字界截字節;把三字節當三個 JavaScript 字元,連數量也取了。

已填假設輸入
紀錄輸入 JSON
原例輸入{"bytes":[228,189,160,49,50],"nameBytes":3}
下載可編輯 CSV ↓

比較兩條實際路徑

更正分成「你」與「12」。每段嚴格解碼,也可查出格式把欄界切在字中間。

錯誤與更正路徑的輸出
路徑輸出 JSON
錯誤路徑{"accepted":true,"name":"你12","quantityText":""}
更正路徑{"accepted":true,"name":"你","quantityText":"12"}
下載可編輯 CSV ↓
本地 Node.js 程序:22.23.3 或 24.14.1
import {DatabaseSync} from 'node:sqlite';
import {TextDecoder} from 'node:util';
import {inflateSync} from 'node:zlib';
import {posix} from 'node:path';
import {createHash} from 'node:crypto';
const rows=(db,sql)=>db.prepare(sql).all().map(r=>({...r}));
const failed=(action)=>{try{action();return null;}catch(e){return {code:e.errcode??e.code??e.name};}};

import assert from 'node:assert/strict';
const run=function run(i,corrected=true){
    const bytes=Uint8Array.from(i.bytes);const decoder=new TextDecoder('utf-8',{fatal:true});
    try{
      if(corrected){return {accepted:true,name:decoder.decode(bytes.slice(0,i.nameBytes)),quantityText:decoder.decode(bytes.slice(i.nameBytes))};}
      const text=decoder.decode(bytes);return {accepted:true,name:text.slice(0,i.nameBytes),quantityText:text.slice(i.nameBytes)};
    }catch{return {accepted:false,error:'field-splits-encoded-character'};}
  };
const cases=[{"label":"misleading base","input":{"bytes":[228,189,160,49,50],"nameBytes":3},"expected":{"accepted":true,"name":"你12","quantityText":""},"corrected":false},{"label":"corrected base","input":{"bytes":[228,189,160,49,50],"nameBytes":3},"expected":{"accepted":true,"name":"你","quantityText":"12"},"corrected":true},{"label":"boundary within character","input":{"bytes":[228,189,160,49,50],"nameBytes":2},"expected":{"accepted":false,"error":"field-splits-encoded-character"},"corrected":true},{"label":"ASCII source boundary","input":{"bytes":[65,66,49,50],"nameBytes":2},"expected":{"accepted":true,"name":"AB","quantityText":"12"},"corrected":true}];
for(const test of cases){
  const actual=run(test.input,test.corrected);
  assert.deepEqual(actual,test.expected,test.label);
  console.log(test.label,actual);
}
下載可執行例子 ↓

下次載入前核邊界

截兩字節會切開「你」,須拒收;兩字節英文名稱則得 AB,後欄仍 12。

可編輯邊界紀錄及預期輸出
情況輸入 JSON預期輸出 JSON
欄界切在多字節字中{"bytes":[228,189,160,49,50],"nameBytes":2}{"accepted":false,"error":"field-splits-encoded-character"}
英文字節欄界{"bytes":[65,66,49,50],"nameBytes":2}{"accepted":true,"name":"AB","quantityText":"12"}
下載可編輯 CSV ↓

此來源的名稱欄應否包括 12?

查看參考答案

不應,三字節配額是「你」,數量「12」屬另外兩字節欄。

相關資源