janeyjhon 发表于 昨天 15:05

上面的代码该怎样改写

FishC 发表于 昨天 15:05

janeyjhon 发表于 2025-01-22 15:05
上面的代码该怎样改写

为了让代码适应 MFC 的文档视图架构,同时把外部文件读取并处理成 UTF-16 格式的功能整合,以下是简化和具体化的代码改写示例:

---

### **完整代码改写方案**

以下代码将一一实现读取外部文件(支持 UTF-8/ANSI/UTF-16),将其内容正确转换为 UTF-16,并显示在基于 `CEditView` 的视图中。

---

### **CDocument 子类实现:文件加载和内容存储**

#### 定义成员变量
在 `CMyDocument`(派生自 `CDocument`)类中,添加成员变量与方法:

// CMyDocument.h
class CMyDocument : public CDocument
{
protected:
    CString m_strContent; // 存储文档内容

public:
    BOOL LoadFile(const CString& filePath); // 文件加载
    CString GetContent() const { return m_strContent; } // 获取 UTF-16 文档数据
};

#### 实现文件加载方法
以下代码实现了对多种编码格式的文件读取,并转换为 UTF-16 存储到 `CString` 中。

// CMyDocument.cpp
#include <fstream>
#include <codecvt>
#include <locale>

BOOL CMyDocument::LoadFile(const CString& filePath)
{
    // 打开文件流 (二进制模式)
    std::ifstream file(CT2A(filePath), std::ios::binary);
    if (!file.is_open())
    {
      AfxMessageBox(_T("无法打开文件!"));
      return FALSE;
    }

    // 读取文件内容到缓冲区
    std::vector<char> buffer((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
    file.close();

    // 检测 BOM (Byte Order Mark) 并判断文件编码
    std::wstring utf16Content;
    if (buffer.size() >= 2 && buffer == (char)0xFF && buffer == (char)0xFE)
    {
      // UTF-16 (Little Endian)
      utf16Content.assign(reinterpret_cast<wchar_t*>(&buffer), (buffer.size() - 2) / 2);
    }
    else if (buffer.size() >= 3 && buffer == (char)0xEF && buffer == (char)0xBB && buffer == (char)0xBF)
    {
      // UTF-8 带 BOM
      std::string utf8Content(buffer.begin() + 3, buffer.end());
      utf16Content = ConvertUTF8ToUTF16(utf8Content);
    }
    else
    {
      // 假设是 ANSI
      std::string ansiContent(buffer.begin(), buffer.end());
      utf16Content = ConvertANSIToUTF16(ansiContent);
    }

    // 存储为 CString 格式
    m_strContent = utf16Content.c_str();
    return TRUE;
}

std::wstring CMyDocument::ConvertUTF8ToUTF16(const std::string& utf8Content)
{
    // 使用 std::wstring_convert 转换 UTF-8 -> UTF-16
    std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
    return converter.from_bytes(utf8Content);
}

std::wstring CMyDocument::ConvertANSIToUTF16(const std::string& ansiContent)
{
    // 使用 MultiByteToWideChar 将 ANSI 转到 UTF-16
    int wcharsNeeded = MultiByteToWideChar(CP_ACP, 0, ansiContent.c_str(), -1, nullptr, 0);
    std::wstring utf16Content(wcharsNeeded, 0);
    MultiByteToWideChar(CP_ACP, 0, ansiContent.c_str(), -1, &utf16Content, wcharsNeeded);
    return utf16Content;
}

---

### **CView 子类实现:显示内容到视图**

在 `CMyView` 类(派生自 `CEditView`)中,通过访问文档数据,将文件内容显示到编辑视图中。

#### 设置视图内容
修改 `OnInitialUpdate()` 方法以显示文档内容:

// CMyView.cpp
void CMyView::OnInitialUpdate()
{
    CEditView::OnInitialUpdate();

    // 获取文档数据
    CMyDocument* pDoc = GetDocument();
    ASSERT_VALID(pDoc);
    if (!pDoc) return;

    // 将文档内容显示到编辑控件
    SetWindowTextW(pDoc->GetContent());
}

#### 获取关联文档实例(`GetDocument`)
确保使用正确的文档类类型:

inline CMyDocument* CMyView::GetDocument() const
{
    return static_cast<CMyDocument*>(m_pDocument);
}

---

### **文件加载流程:从菜单响应加载外部文件**

通过菜单或按钮实现文件加载响应,在 `CMainFrame` 或 `CMyApp` 中触发文件打开对话框并加载内容到文档:

#### 文件打开对话框和加载操作
在主框架中处理 `ID_FILE_OPEN` 菜单项,将文件路径传递给文档的 `LoadFile` 方法:

// CMainFrame.cpp
void CMainFrame::OnFileOpen()
{
    // 打开文件选择对话框
    CFileDialog dlg(TRUE, NULL, NULL, OFN_FILEMUSTEXIST | OFN_HIDEREADONLY,
                  _T("Text Files (*.txt)|*.txt|All Files (*.*)|*.*||"));

    if (dlg.DoModal() == IDOK)
    {
      CString filePath = dlg.GetPathName();

      // 获取当前文档对象
      CMyDocument* pDoc = static_cast<CMyDocument*>(GetActiveDocument());
      if (pDoc && pDoc->LoadFile(filePath))
      {
            // 通知视图更新内容
            pDoc->SetModifiedFlag(FALSE); // 文档没有被修改
            pDoc->UpdateAllViews(NULL);
      }
      else
      {
            AfxMessageBox(_T("加载文件失败!"));
      }
    }
}

#### 添加消息映射
为 `ID_FILE_OPEN` 菜单选项添加消息映射:

// CMainFrame.h
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
    ON_COMMAND(ID_FILE_OPEN, &CMainFrame::OnFileOpen)
END_MESSAGE_MAP()

---

### **运行流程总结**

1. 点击菜单中的 `File > Open`。
2. 选择一个文件(支持 UTF-8/UTF-16/ANSI 编码)。
3. 程序会将文件的内容解析为 UTF-16 并显示在视图中。

---

### **完整后的功能测试**

##### 测试:
- **测试 1**:使用 UTF-8 编码的文件。
内容:
这是 UTF-8 文件
测试:こんにちは

预期结果:正确显示内容,包括多行和中文日文字符。

- **测试 2**:使用 ANSI 编码文件。
内容:
这是 ANSI 文件
测试:中文

预期结果:正确显示 ANSI 编码下的内容。

- **测试 3**:使用 UTF-16 文件(带 BOM)。
内容:
这是 UTF-16 文件
测试:こんにちは

预期结果:正确显示 UTF-16 编码内容。

---

### **特别提示**

1. **多行支持:**
   如果希望编辑视图支持多行数据,在资源编辑器里为控件设置:
   - Style: `MULTILINE`
   - 显示滚动条 (`HSCROLL` 和 `VSCROLL`)

2. **屏幕更新:**
   每次加载或修改内容时,请确保调用 `UpdateAllViews(NULL)`,以同步视图内容。

如果在实现过程中有任何细节问题,请随时反馈!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

janeyjhon 发表于 昨天 15:22

从文档视图中获取的文本
CString strText; //文本框里的字符串
CEditView::GetWindowText(strText);//获取文本框里的字符串
怎样变成utf-16形式的字符

FishC 发表于 昨天 15:23

janeyjhon 发表于 2025-01-22 15:22
从文档视图中获取的文本
CString strText; //文本框 ...

MFC 的 `CString` 默认使用宽字符(`wchar_t`),其内部存储即是 **UTF-16** 编码(前提是项目已设置为 Unicode 编译方式)。因此,**如果输入的文本来自 `CEditView::GetWindowText`,文本已经是 UTF-16 格式**,您不需要进行额外的转换。

不过,如果需要确保从外部文件或某些异常来源(例如 ANSI 或 UTF-8 编码)获取的文本经过正确处理成为 UTF-16 格式字符,可以按照以下方法进行操作。

---

### **确保输入是 UTF-16 的实现步骤**

#### 1. **检查是否已经是 UTF-16**
- 从 `CEditView` 中获取字符串后(`GetWindowText` 返回的 `CString`),它应已经是宽字符形式(即 UTF-16 编码)。
- 您可以直接使用:

CString strText;
GetWindowText(strText);

如果您需要进一步操作字符串为 `std::wstring` 或 `wchar_t*` 使用:

std::wstring utf16String = strText.GetString(); // 转换为 std::wstring
const wchar_t* utf16CStr = strText.GetString(); // 获取 UTF-16 字符指针

这样,您获取的文本已经是符合 UTF-16 标准格式了。

---

#### 2. **如果可能的内容编码不是 UTF-16(例如 UTF-8 或 ANSI)**
若此字符串不是 UTF-16 格式(比如外部来源为 `UTF-8` 或 `ANSI`),您需要手动将其转换为 UTF-16。以下代码展示了如何处理:

##### **示例:从 UTF-8 转换为 UTF-16**
如果您确定要处理的是 UTF-8 格式,可以使用 Windows API 的 `MultiByteToWideChar` 来进行转换:

CString ConvertUTF8ToUTF16(const std::string& utf8Str) {
    int utf16Length = MultiByteToWideChar(CP_UTF8, 0, utf8Str.c_str(), -1, NULL, 0);
    if (utf16Length == 0) {
      return L""; // 转换失败返回空字符串
    }

    // 分配足够的缓冲区存储 UTF-16 字符
    std::wstring utf16Str(utf16Length, 0);
    MultiByteToWideChar(CP_UTF8, 0, utf8Str.c_str(), -1, &utf16Str, utf16Length);

    return CString(utf16Str.c_str());
}

##### **使用示例:**
std::string utf8String = "你好,世界"; // UTF-8 编码的字符串
CString utf16CString = ConvertUTF8ToUTF16(utf8String);

---

##### **从 ANSI 编码转换为 UTF-16**
如果您需要从系统默认的 ANSI(单字节编码)转换为 UTF-16,同样使用 `MultiByteToWideChar`:

CString ConvertANSIToUTF16(const std::string& ansiStr) {
    // 获取系统默认代码页
    int utf16Length = MultiByteToWideChar(CP_ACP, 0, ansiStr.c_str(), -1, NULL, 0);
    if (utf16Length == 0) {
      return L"";
    }

    // 分配缓冲区并进行转换
    std::wstring utf16Str(utf16Length, 0);
    MultiByteToWideChar(CP_ACP, 0, ansiStr.c_str(), -1, &utf16Str, utf16Length);
    return CString(utf16Str.c_str());
}

##### **使用示例:**
std::string ansiString = "ANSI 编码内容";
CString utf16CString = ConvertANSIToUTF16(ansiString);

---

### **完整项目示例:从 `CEditView` 确保是 UTF-16**

以下代码包含完整逻辑,从 `CEditView` 中读取文本,确定其已经是 UTF-16。如需处理非 UTF-16 编码的输入,也一并进行适当转换:

void CMyView::OnProcessText()
{
    CString strText;
    GetWindowText(strText); // 获取 CEditView 中的文本

    // 假设来源是已知编码(例如 UTF-8),需要转换
    std::string utf8Str = CT2A(strText); // 将 CString 转为 std::string(假设来源是 UTF-8)
    CString utf16Str = ConvertUTF8ToUTF16(utf8Str); // 转为 UTF-16

    // 显示转换后的字符串 (确保正确转换)
    AfxMessageBox(utf16Str);
}

// 工具函数:从 UTF-8 转换为 UTF-16
CString ConvertUTF8ToUTF16(const std::string& utf8Str)
{
    int utf16Length = MultiByteToWideChar(CP_UTF8, 0, utf8Str.c_str(), -1, NULL, 0);
    if (utf16Length == 0) {
      return L"";
    }

    std::wstring utf16Str(utf16Length, 0);
    MultiByteToWideChar(CP_UTF8, 0, utf8Str.c_str(), -1, &utf16Str, utf16Length);
    return CString(utf16Str.c_str());
}

---

### **注意事项**

1. **确保工程使用 Unicode 编译**
   - 在 Visual Studio 中,前往项目属性 -> 常规,确保 `字符集` 选项设置为 **“使用 Unicode 字符集”**。
   - 如果使用多字节字符集(MBCS),大部分 `CString` 操作会默认处理为类似 ANSI 编码,而不是 UTF-16。

2. **编辑控件的内容类型**
   - 在 `CEditView` 或 `CEdit` 控件中,内容自然存储为宽字符(UTF-16),如果您手动向其写入非宽字符内容,可能会导致显示问题。

3. **避免嵌套多次转换**
   - 如果输入来源已经是 UTF-16 千万不要再反复转码(如 UTF-16 -> UTF-8 -> UTF-16),否则可能引起数据破坏。

---

### **总结**

- **如果来源是 `GetWindowText` 从 `CEditView` 提取的内容,默认已经是 UTF-16,无需额外操作。**
- 如果文本来源是非 UTF-16 编码(如外部文件或 ANSI 内容),使用 `MultiByteToWideChar` 进行转换即可。

如果还有其他场景需要特殊处理,例如更复杂的编码格式(GBK 等),可以继续向我提问!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

FishC 发表于 昨天 15:24

janeyjhon 发表于 2025-01-22 15:22
从文档视图中获取的文本
CString strText; //文本框 ...

`CString` 本身在 MFC 中默认是 Unicode(即 `UTF-16` 编码)的宽字符形式。所以,如果您的项目是以 Unicode 模式编译的,那么 `CString` 已经是 UTF-16 形式的字符,并不需要做额外的转换。

### **关键点确认**

1. **MFC 的编码模式**
   请确认您的 MFC 项目是否设置为 **Unicode 编码** 模式。
   在 Visual Studio 中检查:
   - 右键项目 -> "属性"。
   - 选择 "配置属性" -> "常规"。
   - 确保 "字符集" 设置为 `使用 Unicode 字符集`。
   
   如果这里没有使用 Unicode 字符集,那么 `CString` 的内部表示可能是 ANSI(单字节字符),这个时候需要进行转换。

2. **`CEditView::GetWindowText` 返回的结果**
   `CEditView` 的 `GetWindowText` 方法会自动返回一个 `CString`,在 Unicode 项目中,其内容已经是 UTF-16 形式的。

### **直接获取 UTF-16 内容**

以下代码展示如何通过 `CEditView::GetWindowText` 获取文本并确认其为 UTF-16:

CString strText; // 文本框内容
CEditView::GetWindowText(strText); // 获取文本框内的内容

// 确认 strText 就是UTF-16,因为 CString 已经是宽字符表示
std::wstring utf16String = strText.GetString(); // 转换为 std::wstring

// 直接在调试中输出
wprintf(L"UTF-16 文本: %s\n", utf16String.c_str());

上面的代码会将文本转换为 UTF-16 并存储到 `std::wstring` 中进行处理。

---

### **从 ANSI(单字节)到 UTF-16 的转换**

如果发现您项目中使用的是 ANSI 编码或者外部数据是 ANSI 编码的,可以将 `CString`(ANSI 格式)转换为 UTF-16。

**方法:使用 `MultiByteToWideChar`**

CString strText; // 文本框内容
CEditView::GetWindowText(strText); // 获取文本框内内容

// 假设 strText 是 ANSI,需要手动转换到 UTF-16
std::string ansiString(CT2A(strText)); // 转换 CString 到 std::string (ANSI)
int wideCharLength = MultiByteToWideChar(CP_ACP, 0, ansiString.c_str(), -1, NULL, 0);
std::wstring utf16String(wideCharLength, 0);
MultiByteToWideChar(CP_ACP, 0, ansiString.c_str(), -1, &utf16String, wideCharLength);

// 此时 utf16String 是 UTF-16 内容

---

### **从 UTF-8 到 UTF-16 的转换**

如果外部数据是 UTF-8 格式,但您需要在代码中将其转换为 UTF-16,可以使用以下方法。

**方法:使用标准的 `std::wstring_convert`**

CString strText; // 文本框内容
CEditView::GetWindowText(strText); // 获取文本框内内容

// 假设 strText 内容是 UTF-8
std::string utf8String(CT2A(strText)); // 转换 CString 到 std::string (UTF-8)
std::wstring_convert convert;         // 定义转换器
std::wstring utf16String = convert.from_bytes(utf8String);

// 输出 UTF-16 内容
wprintf(L"转换后的 UTF-16 文本: %s\n", utf16String.c_str());

---

### **从外部文件读取到 `CEditView` 并检测转换**

如果您是获取文本内容然后需要确保其编码为 `UTF-16`,以下是完整流程:

#### 步骤实现:
1. 从 `CEditView` 获取内容。
2. 如果文本数据是 ANSI 或其他编码,手动转换到 UTF-16。
3. 使用转换后的 UTF-16 数据进行后续操作。

**代码示例:**
void CMyView::ProcessEditText()
{
    // 获取 CEditView 中的内容
    CString strText;
    CEditView::GetWindowText(strText);

    // 确认字符串已经是 UTF-16
    std::wstring utf16Result = strText.GetString();
    wprintf(L"从文本框中获取的 UTF-16 文本: %s\n", utf16Result.c_str());

    // 如果假设字符串是 UTF-8 或 ANSI,则需要进行转换
    std::string utf8String(CT2A(strText, CP_UTF8));
    std::wstring_convert convert;
    std::wstring utf16FromUtf8 = convert.from_bytes(utf8String);

    // 输出重新转换的内容
    wprintf(L"从 UTF-8 转换到 UTF-16 的文本: %s\n", utf16FromUtf8.c_str());
}

---

### **注意重点**
1. **已有 Unicode(UTF-16):**
   如果您的项目已经启用了 Unicode(默认 `CString` 为 UTF-16),则无需任何额外转换,直接使用 `CString.GetString()` 即可获取 UTF-16 数据。

2. **需要手动转换:**
   - ANSI -> UTF-16:使用 `MultiByteToWideChar`。
   - UTF-8 -> UTF-16:使用 `std::wstring_convert` 或基于 `WideCharToMultiByte` 的方法。

3. **外部输入的编码检测:**
   如果数据来自文件或其他来源,您需要确认其是否有 BOM(字节序标记),以区分 `UTF-8`/`UTF-16` 和 `ANSI`。

如果还有其他细节问题,请进一步说明,我会协助具体场景的解决方案!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

janeyjhon 发表于 昨天 15:43

我这个是从外部弄进来的文字在CEditView中显示估计计是utf-8,怎么样变成utf-16

FishC 发表于 昨天 15:45

janeyjhon 发表于 2025-01-22 15:43
我这个是从外部弄进来的文字在CEditView中显示估计计 ...

如果您确认从外部加载的文件或文字内容是 UTF-8 编码,并且需要在 `CEditView` 中显示为 UTF-16(MFC 的 `CString` 和 `CEditView` 使用的默认编码),您可以通过读取文件后将其从 UTF-8 转换到 UTF-16 格式。以下是完整的实现步骤。

---

### **关键实现步骤**
1. **从文件或外部加载字符串**
   - 使用 `std::ifstream` 或 MFC 的文件读取类如 `CStdioFile` 将文本内容读取为 `std::string`。

2. **转换 UTF-8 到 UTF-16**
   - 使用 Windows API `MultiByteToWideChar` 转换编码。
   - 也可以使用标准 C++ 的 `std::wstring_convert` 进行转换。

3. **将 UTF-16 内容设置到编辑框(`CEditView`)**
   - 通过 `SetWindowTextW` 方法将转换后的 UTF-16 文本显示在编辑框中。

---

### **完整代码实现**

#### **文件读取和转码功能实现**

以下代码实现加载文件内容(假设为 UTF-8)并显示在 `CEditView` 控件中:

#include <fstream>
#include <string>
#include <codecvt>
#include <vector>

// 工具函数:将 UTF-8 转换为 UTF-16
CString ConvertUTF8ToUTF16(const std::string& utf8Str) {
    int utf16Length = MultiByteToWideChar(CP_UTF8, 0, utf8Str.c_str(), -1, NULL, 0);
    if (utf16Length == 0) {
      return L""; // 转换失败返回空
    }

    // 分配缓冲区用于存储 UTF-16 数据
    std::wstring utf16Str(utf16Length, 0);
    MultiByteToWideChar(CP_UTF8, 0, utf8Str.c_str(), -1, &utf16Str, utf16Length);

    return CString(utf16Str.c_str());
}

// 从文件读取内容 (假设文件是 UTF-8 编码)
bool LoadUTF8FileToCString(const CString& filePath, CString& output) {
    // 打开文件
    std::ifstream inputFile(CT2A(filePath), std::ios::binary);
    if (!inputFile.is_open()) {
      AfxMessageBox(L"无法打开文件");
      return false;
    }

    // 读取文件内容到 std::string
    std::string fileContent((std::istreambuf_iterator<char>(inputFile)),
                            std::istreambuf_iterator<char>());
    inputFile.close();

    // 转换为 UTF-16 格式的 CString
    output = ConvertUTF8ToUTF16(fileContent);
    return true;
}

---

#### **在 `CEditView` 中显示文本**

在您的 `CView` 类中实现从文件加载并显示的功能:

void CMyView::OnLoadAndDisplayFile() {
    // 文件选择对话框
    CFileDialog fileDlg(TRUE, NULL, NULL, OFN_FILEMUSTEXIST | OFN_HIDEREADONLY,
                        L"文本文件 (*.txt)|*.txt|所有文件 (*.*)|*.*||");

    if (fileDlg.DoModal() == IDOK) {
      // 获取文件路径
      CString filePath = fileDlg.GetPathName();

      // 加载文件并转换为 UTF-16
      CString utf16Text;
      if (!LoadUTF8FileToCString(filePath, utf16Text)) {
            AfxMessageBox(L"加载文件失败!");
            return;
      }

      // 设置到编辑框中显示
      SetWindowTextW(utf16Text); // CEditView 显示 UTF-16 文本
    }
}

---

### **完整调用流程测试**

#### **绑定菜单或按钮事件**
将 `OnLoadAndDisplayFile` 方法绑定到一个菜单项或按钮响应中。例如:

BEGIN_MESSAGE_MAP(CMyView, CEditView)
    ON_COMMAND(ID_FILE_LOADTEXT, &CMyView::OnLoadAndDisplayFile)
END_MESSAGE_MAP()

对于菜单选项:在资源编辑器中为 `ID_FILE_LOADTEXT` 创建对应的菜单并绑定事件。

---

#### **运行测试**
1. 运行程序,选择打开的文件。
2. 选择包含 UTF-8 编码带有多语言(例如中文、日文等字符)的文件。
3. 程序会读取文件内容,将其转换为 UTF-16,并显示在编辑框中。

---

### **注意事项**

1. **文件的编码格式**
   - 必须确认文件确实是 UTF-8 编码。如果文件是 ANSI、UTF-16 或其他编码,则需要根据其实际编码类型进行适当修改和处理。
   - 文件是 UTF-16(带 BOM)时,需要不同的方法读取其内容。

2. **编辑框支持多行显示**
   - 如果需要支持多行输入,可以在资源编辑器中设置编辑框的属性为 `Multiline`。
   - 同时启用水平和垂直滚动条。

3. **编码转换异常处理**
   - 使用 `MultiByteToWideChar` 转换时,如果发现文件中有非法的 UTF-8 字符,可能会导致转换失败。在这种情况下,您需要捕获错误并提示用户。

---

### **如果文件可能是 UTF-8、UTF-16 或 ANSI 任意编码格式**

我们可以检测文件的 BOM(Byte Order Mark)来确定文件的编码,并有选择性地进行解析。以下是一个扩展示例:

#### **扩展:检测文件编码并处理**

enum FileEncoding {
    UTF8_WITH_BOM,
    UTF16_LE,
    UTF16_BE,
    ANSI,
    UNKNOWN
};

// 检测文件编码
FileEncoding DetectFileEncoding(const std::string& filePath) {
    std::ifstream file(filePath, std::ios::binary);
    if (!file.is_open()) return UNKNOWN;

    unsigned char bom = {0};
    file.read(reinterpret_cast(bom), 3);
    file.close();

    if (bom == 0xEF && bom == 0xBB && bom == 0xBF) {
      return UTF8_WITH_BOM;
    }
    if (bom == 0xFF && bom == 0xFE) {
      return UTF16_LE;
    }
    if (bom == 0xFE && bom == 0xFF) {
      return UTF16_BE;
    }

    return ANSI; // 不含 BOM,假设是 ANSI
}

根据检测到的编码调用不同的处理逻辑:

if (encoding == UTF8_WITH_BOM) {
    // 从 UTF-8 加载
} else if (encoding == UTF16_LE) {
    // 从 UTF-16 LE 加载
} else if (encoding == ASCII) {
    // ANSI 处理逻辑
} else {
    AfxMessageBox(L"未知或不支持的文件编码!");
}

---

如果通过以上实现,您的文本应该能够正确从文件加载并显示到 CEditView 中。如果仍有疑问,可以继续提问!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

janeyjhon 发表于 昨天 16:30

怎么样确保从CEditVew读取的是utf-16编码,如何检测

janeyjhon 发表于 昨天 16:33

//std::string utf8Str = CT2A(input);
//int utf16Length = MultiByteToWideChar(CP_UTF8, 0, utf8Str.c_str(), -1, NULL, 0);
//if (utf16Length == 0) {
//        return L"";
//}

//std::wstring utf16Str(utf16Length, 0);
//MultiByteToWideChar(CP_UTF8, 0, utf8Str.c_str(), -1, &utf16Str, utf16Length);

janeyjhon 发表于 昨天 16:34

这样转不正确,转成utf-16都是方块加问号

janeyjhon 发表于 昨天 16:36

根本在while那块进不去

janeyjhon 发表于 昨天 16:39

我说一下我是怎么操作,首先新建一个文档视图,把别处的文字粘过来,复制到单文档视了图中,然后用CEditView读取字符串,再运用你的上面的代码想让〖HT《MS Mincho》〗和〖HT〗之间的标点符号加〖KG1*2〗,结果出现过while根本进不去

janeyjhon 发表于 昨天 16:40

while (std::regex_search(str.cbegin() + lastPos, str.cend(), matches, reg)) {
        size_t matchStart = matches.position(0) + lastPos;
        size_t matchEnd = matchStart + matches.length(0);

        result += str.substr(lastPos, matchStart - lastPos);

        // 提取中间内容
        std::wstring matchedText = matches.str();

        // 添加标记到标点符号
        std::wstring modifiedText;
        for (wchar_t c : matchedText) {
                if (c == L',' || c == L'。' || c == L'、' || c == L'!' || c == L'?') {
                        modifiedText += L"〖KG1*2〗";
                }
                modifiedText += c;
        }

        result += L"〖HT《MS Mincho》〗" + modifiedText + L"〖HT〗";

        lastPos = matchEnd;
}不运行这段代码

janeyjhon 发表于 昨天 16:48

        setlocale(LC_ALL, "Japanese_Japan.932");
        // TODO: 在此添加命令处理程序代码
        CString strText; //文本框里的字符串
        CEditView::GetWindowTextW(strText);//获取文本框里的字符串
CString CMFCApplication1View::ProcessString(CString& input)
{
        // TODO: 在此处添加实现代码.
       
        size_t lastPos = 0;
        std::wstring result;

        while (std::regex_search(str.cbegin() + lastPos, str.cend(), matches, reg)) {
                size_t matchStart = matches.position(0) + lastPos;
                size_t matchEnd = matchStart + matches.length(0);

                result += str.substr(lastPos, matchStart - lastPos);

                // 提取中间内容
                std::wstring matchedText = matches.str();

                // 添加标记到标点符号
                std::wstring modifiedText;
                for (wchar_t c : matchedText) {
                        if (c == L',' || c == L'。' || c == L'、' || c == L'!' || c == L'?') {
                                modifiedText += L"〖KG1*2〗";
                        }
                        modifiedText += c;
                }

                result += L"〖HT《MS Mincho》〗" + modifiedText + L"〖HT〗";

                lastPos = matchEnd;
        }
       
        result += str.substr(lastPos);
        CString ret=result.c_str();
       
        return        ret;
}

janeyjhon 发表于 昨天 16:48

我的代码

janeyjhon 发表于 昨天 16:54

        //std::string utf8Str = CT2A(input);
        //int utf16Length = MultiByteToWideChar(CP_UTF8, 0, utf8Str.c_str(), -1, NULL, 0);
        //if (utf16Length == 0) {
        //        return L"";
        //}

        //std::wstring utf16Str(utf16Length, 0);
        //MultiByteToWideChar(CP_UTF8, 0, utf8Str.c_str(), -1, &utf16Str, utf16Length);
中间把这段写进去发觉也不行,utf-16全是方块加问号
页: 1 [2]
查看完整版本: 下面的用Mfc怎么实现