在 Windows 上使用 fgets() 从 stdin 读取 UTF-8

2023-11-29

我正在尝试读取 UTF-8 字符串stdin using fgets()。控制台输入模式已设置为CP_UTF8前。我还在 PowerShell 中将控制台字体设置为 Lucida Console。最后,我通过打印德语来验证 UTF-8 输出是否正常工作Ä(UTF-8 格式:0xC3,0x84)到控制台使用printf()。这是工作正常但是fgets()似乎无法从控制台读取UTF-8。这是一个小测试程序:

#include <stdio.h>  
#include <windows.h>

int main(int argc, char *argv[])
{
    unsigned char s[64];

    memset(s, 0, 64);

    SetConsoleOutputCP(CP_UTF8);    
    SetConsoleCP(CP_UTF8);

    printf("UTF-8 Test: %c%c\n", 0xc3, 0x84);  // print Ä

    fgets(s, 64, stdin);

    printf("Result: %d %d\n", s[0], s[1]);

    return 0;
}

当运行该程序并输入“Ä”然后按 ENTER 键时,它只会打印以下内容:

Result: 0 0

即没有写入任何内容s。然而,当输入“A”时,我得到以下正确结果:

Result: 65 10

那么我怎样才能使fgets()请在 Windows 上使用 UTF-8 字符吗?

EDIT

根据 Barmak 的解释,我现在已经更新了我的代码以使用wchar_t函数而不是 ANSI 函数。然而,它仍然不起作用。这是我的代码:

#include <stdio.h>
#include <io.h>
#include <fcntl.h>

#include <windows.h>

int main(int argc, char *argv[])
{
    wchar_t s[64];

    memset(s, 0, 64 * sizeof(wchar_t));

    _setmode(_fileno(stdin), _O_U16TEXT);       
    fgetws(s, 64, stdin);

    wprintf(L"Result: %d\n", s[0]);

    return 0;
}   

进入时A程序打印Result: 3393但我希望它是65。进入时Ä程序打印Result: 0但我希望它是196。那里到底发生了什么事?为什么现在连 ASCII 字符都不起作用了?我的旧程序仅使用fgets()对于 ASCII 字符,如A,它仅对非 ASCII 字符失败,例如Ä。但新版本甚至不适用于 ASCII 字符,或者是3393正确的结果为A?我希望它是65。我现在很困惑...请帮忙!


Windows 使用 UTF 16。Windows 控制台很可能不支持 UTF8。

将 UTF16 与宽字符串函数一起使用(wcsxxx代替strxxx)。然后您可以使用WideCharToMultiByte将 UTF16 转换为 UTF8。例子:

#include <stdio.h>
#include <string.h>
#include <io.h> //for _setmode
#include <fcntl.h> //for _O_U16TEXT

int main()
{
    _setmode(_fileno(stdout), _O_U16TEXT);
    _setmode(_fileno(stdin), _O_U16TEXT);
    wchar_t s[64];
    fgetws(s, 64, stdin);
    _putws(s);
    return 0;
}

请注意,调用后不能使用 ANSI 打印函数_setmode(_fileno(stdout), _O_U16TEXT),必须重置。您可以尝试类似下面的函数来重置文本模式。

char* mygets(int wlen)
{
    //may require fflush here, see _setmode documentation
    int save = _setmode(_fileno(stdin), _O_U16TEXT);
    wchar_t *wstr = malloc(wlen * sizeof(wchar_t));
    fgetws(wstr, wlen, stdin);

    //make UTF-8:
    int len = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, 0, 0, 0, 0);
    if (!len) return NULL;
    char* str = malloc(len);
    WideCharToMultiByte(CP_UTF8, 0, wstr, -1, str, len, 0, 0);
    free(wstr);

    _setmode(_fileno(stdin), save);
    return str;
}

void myputs(const char* str)
{
    //may require fflush here, see _setmode documentation
    int save = _setmode(_fileno(stdout), _O_U16TEXT);

    //make UTF-16
    int wlen = MultiByteToWideChar(CP_UTF8, 0, str, -1, 0, 0);
    if (!wlen) return;
    wchar_t* wstr = malloc(wlen * sizeof(wchar_t));
    memset(wstr, 0, wlen * 2);
    MultiByteToWideChar(CP_UTF8, 0, str, -1, wstr, wlen);

    _putws(wstr);
    _setmode(_fileno(stdout), save);
}

int main()
{
    char* utf8 = mygets(100);
    if (utf8)
    {
        myputs(utf8);
        free(utf8);
    }
    return 0;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 Windows 上使用 fgets() 从 stdin 读取 UTF-8 的相关文章

  • 属性对象什么时候创建?

    由于属性实际上只是附加到程序集的元数据 这是否意味着属性对象仅根据请求创建 例如当您调用 GetCustomAttributes 时 或者它们是在创建对象时创建的 或者 前两个的组合 在由于 CLR 的属性扫描而创建对象时创建 从 CLR
  • 自动从 C# 代码进行调试过程并读取寄存器值

    我正在寻找一种方法来读取某个地址的 edx 注册表 就像这个问题中所问的那样 读取eax寄存器 https stackoverflow com questions 16490906 read eax register 虽然我的解决方案需要用
  • 如何在 Unity 中从 RenderTexture 访问原始数据

    问题的简短版本 我正在尝试访问 Unity 中 RenderTexture 的内容 我一直在使用 Graphics Blit 使用自己的材质进行绘制 Graphics Blit null renderTexture material 我的材
  • Func 方法参数的首选命名约定是什么?

    我承认这个问题是主观的 但我对社区的观点感兴趣 我有一个缓存类 它采用类型的缓存加载器函数Func
  • 嵌入式系统中的malloc [重复]

    这个问题在这里已经有答案了 我正在使用嵌入式系统 该应用程序在 AT91SAMxxxx 和 cortex m3 lpc17xxx 上运行 我正在研究动态内存分配 因为它会极大地改变应用程序的外观 并给我更多的力量 我认为我唯一真正的路线是为
  • SSH 主机密钥指纹与模式 C# WinSCP 不匹配

    我尝试通过 WinSCP 使用 C 连接到 FTPS 服务器 但收到此错误 SSH 主机密钥指纹 与模式不匹配 经过大量研究 我相信这与密钥的长度有关 当使用 服务器和协议信息 下的界面进行连接时 我从 WinSCP 获得的密钥是xx xx
  • 将字符串从非托管代码传递到托管

    我在将字符串从非托管代码传递到托管代码时遇到问题 在我的非托管类中 非托管类 cpp 我有一个来自托管代码的函数指针 TESTCALLBACK FUNCTION testCbFunc TESTCALLBACK FUNCTION 接受一个字符
  • c 中的错误:声明隐藏了全局范围内的变量

    当我尝试编译以下代码时 我收到此错误消息 错误 声明隐藏了全局范围内的变量 无效迭代器 节点 根 我不明白我到底在哪里隐藏或隐藏了之前声明的全局变量 我怎样才能解决这个问题 typedef node typedef struct node
  • 当 Cortex-M3 出现硬故障时如何保留堆栈跟踪?

    使用以下设置 基于 Cortex M3 的 C gcc arm 交叉工具链 https launchpad net gcc arm embedded 使用 C 和 C FreeRtos 7 5 3 日食月神 Segger Jlink 与 J
  • 使用 LINQ 查找列表中特定类型的第一个元素

    使用 LINQ 和 C 在元素列表中查找特定类型的第一个项目的最短表示法是什么 var first yourCollection OfType
  • 线程、进程和 Application.Exit()

    我的应用程序由主消息循环 GUI 和线程 Task Factory 组成 在线程中我调用一些第三方应用程序var p new Process 但是当我调用Application Exit 在消息循环中 我可以看到在线程中启动的进程仍在内存中
  • 是否有比 lex/flex 更好(更现代)的工具来生成 C++ 分词器?

    我最近将源文件解析添加到现有工具中 该工具从复杂的命令行参数生成输出文件 命令行参数变得如此复杂 以至于我们开始允许它们作为一个文件提供 该文件被解析为一个非常大的命令行 但语法仍然很尴尬 因此我添加了使用更合理的语法解析源文件的功能 我使
  • Windows 10 中 Qt 桌面应用程序的缩放不当

    我正在为 Windows 10 编写一个简单的 Qt Widgets Gui 应用程序 我使用的是 Qt 5 6 0 beta 版本 我遇到的问题是它根本无法缩放到我的 Surfacebook 的屏幕上 这有点难以判断 因为 SO 缩放了图
  • 如何使用 PowerShell 2 的导出 csv 附加文件?

    filesremoved export csv Path E Code powershell logs filesremoved txt NoTypeInformation 我也尝试过 filesremoved export csv Pat
  • 可空属性与可空局部变量

    我对以下行为感到困惑Nullable types class TestClass public int value 0 TestClass test new TestClass Now Nullable GetUnderlyingType
  • AccessViolationException 未处理

    我正在尝试使用史蒂夫 桑德森的博客文章 http blog stevensanderson com 2010 01 28 editing a variable length list aspnet mvc 2 style 为了在我的 ASP
  • 使用 powershell 编辑 XML

    好吧 我感觉自己像个大白痴 为了工作中的管理目的 我使用 Powershell 已经有一段时间了 也就是说 编写脚本不是我的强项 现在 我正在尝试编写一个 PS 脚本 将一个部分添加到一堆机器上的 XML 中 以添加设置来解决我们在某个应用
  • EPPlus Excel 更改单元格颜色

    我正在尝试将给定单元格的颜色设置为另一个单元格的颜色 该单元格已在模板中着色 但worksheet Cells row col Style Fill BackgroundColor似乎没有get财产 是否可以做到这一点 或者我是否必须在互联
  • 已过时 - OpenCV 的错误模式

    我正在使用 OpenCV 1 进行一些图像处理 并且对 cvSetErrMode 函数 它是 CxCore 的一部分 感到困惑 OpenCV 具有三种错误模式 叶 调用错误处理程序后 程序终止 Parent 程序没有终止 但错误处理程序被调
  • ListDictionary 类是否有通用替代方案?

    我正在查看一些示例代码 其中他们使用了ListDictionary对象来存储少量数据 大约 5 10 个对象左右 但这个数字可能会随着时间的推移而改变 我使用此类的唯一问题是 与我所做的其他所有事情不同 它不是通用的 这意味着 如果我在这里

随机推荐

  • 使 IE 10 重复 svg 背景

    我有一个 svg 我将其用作身体的背景 我正在使用 x repeat 它可以在 chrome 和 FF 中工作 但在 ie10 实际上是 ie11 beta 中 背景被压扁 并且在每个 x repeat 之间有巨大的条形 链接在这里http
  • gm_auth 函数与 gargle_oauth_cache 停止工作

    我编写了从 gmail 下载电子邮件的 R 脚本 我已将 gm auth 与 gargle oauth cache 一起使用 library gmailr gm auth configure path path json gm auth e
  • python-selenium 有没有办法等待页面的所有元素加载完毕?

    我要求一般检查页面的所有元素是否已加载 有没有办法基本上检查一下 在具体的示例中 有一个页面 我单击某个按钮 然后我必须等到单击 下一步 按钮 然而 这个 下一步 按钮始终可用 可选择和单击 那么如何使用 selenium 检查页面的 状态
  • 单击产品标签时标签计数会自动更改

    我正在使用 Shopify 我在集合页面中 我获取所有带有标签计数的过滤器 例如 All Products Apple 4 Banana 2 Orange 1 Mango 8 现在 当我单击任何标签 例如我单击香蕉 时 它将显示香蕉产品 现
  • 无法将 io.ktor 导入到 Android Studio 中的 KMM 公共模块

    所以我是 Kotlin Multiplatform Mobile 和一般移动开发的新手 我正在尝试在这里遵循本教程关于 KMM 教程在我的项目中使用 Ktor 添加依赖后 如build gradle kts所示 下面 commonMain
  • 国际化不起作用或者我不知道如何使其起作用

    Settings py常量 TIME ZONE Europe Vilnius LANGUAGE CODE lt USE I18N True USE L10N True USE TZ True MIDDLEWARE CLASSES djang
  • 使用 C# 的 Magento SOAP API V2:需要 HTTP 身份验证的商店出现问题

    修改后的问题我修改了原来的问题 如下所示 以便我可以将问题的一部分标记为已回答 所以这里是 我构建了一个工具来从客户商店 magento 导入销售订单 以便集成到我们的旧订单处理系统中 我有五家商店可供进口 其中之一在其商店中设置了 HTT
  • 计算 git 存储库中的行数

    如何计算 git 存储库中所有文件中存在的总行数 git ls files给我一个 git 跟踪的文件列表 我正在寻找一个命令cat所有这些文件 就像是 git ls files cat all these files wc l xargs
  • 元素嵌套时覆盖 em 字体大小

    当您有嵌套元素时 如何覆盖 font size 属性 使用 重要的似乎没有任何效果 div font size 6em p font size 1em important span font size 1em div span span s
  • 分页循环Google脚本

    我完全是个新手 想出了以下 Google 脚本来发送 GET 请求 然后将响应解析到 Google Sheet 中 我只能在第一页上请求 50 个项目 并且我尝试寻找一种循环页面的方法 直到获得我请求的所有数据 我确信如果有人能指出我正确的
  • 为什么我在 ggtext 的轴标签中使用 png 徽标的代码不起作用

    我正在尝试学习 改进 R 中的可视化 这个精彩的帖子 对于第一部分 它似乎效果很好 但是轴文本被徽标替换的部分不起作用 显示的错误是 Error in png readPNG get file path native TRUE file i
  • 如何将带参数的 WordPress 短代码传递给模板

    我有带有子主题的模板 我编辑子模板 function php 目标是创建简短的代码 其中包含参数和模板文件的一部分 我的函数如下所示 function my shortcode atts array extract shortcode at
  • jQuery 类选择器不起作用,id 选择器仅适用于“body”

    我正在尝试使用 jquery 应用 CSS 值 但类选择器或 id 选择器由于某种原因不起作用 这是我的小提琴 如您所见 如果我使用 id kitten 则不会发生任何情况 HTML div div Script function var
  • 签名的小程序可以与它们所源自的不同主机连接吗?

    我需要一个小程序来打开套接字并与侦听的服务器进行通信 小程序下载到的本地主机 最终用户计算机 与我读到的有关小程序安全性的内容相反 似乎甚至签名的小程序 无法打开到下载它们的不同主机的套接字 在同一台机器上它工作得很好 我已经使用 self
  • angularjs 路由可以有可选的参数值吗?

    我可以设置带有可选参数的路线 相同的模板和控制器 但如果某些参数不存在 则应忽略它们 因此 与其编写以下两条规则 而只编写一条 module config routeProvider function routeProvider route
  • 在 SQL Server 视图中使用表值函数

    如果我尝试以下查询 我有一个表值函数可以正常工作 SELECT FROM dbo GetScheduleForEmployee AS schedule 但是 如果我尝试使用该查询创建视图 则会收到 参数太少 错误 表值函数和视图有限制吗 这
  • 如何通过使用delphi 7中的API获取Netstat信息

    我的任务是查找 abt n w 信息 或者 Windows 中 netstat 命令给出的信息 现在 我被告知使用一些 API 来提取该信息 任何可用于 delphi 7 执行此任务的 API 都会有所帮助 我遇到过这个 API 即 IP
  • 递归CTE概念混淆

    我试图理解在 SQL 代码中使用 CTE 的概念 我已经浏览了许多解释这个概念的在线帖子 但我无法理解它如何迭代以呈现分层数据 解释 R CTE 的广泛使用的示例之一是 Employee 和 ManagerID 示例 如下所示 USE Ad
  • 如何在IIS服务器上的conda基础环境中部署python Flask应用程序?

    我想在 IIS 服务器上部署 Flask REST API 应用程序来发布一些 ML API 我已经安装了 Anaconda 来在其基本环境中运行该应用程序 因为我有一些数据科学库需要导入 我按照此链接进行部署 它对于教程中给出的示例运行良
  • 在 Windows 上使用 fgets() 从 stdin 读取 UTF-8

    我正在尝试读取 UTF 8 字符串stdin using fgets 控制台输入模式已设置为CP UTF8前 我还在 PowerShell 中将控制台字体设置为 Lucida Console 最后 我通过打印德语来验证 UTF 8 输出是否