Visual C++ 和 u8 前缀
visual C++ and u8 prefix
我在 visual studio 预览版中编写了一个 HTTP 服务器,我添加 <meta charset="utf-8">
以使用 UTF-8 作为内容编码。
问题是当我在字符串文字上使用 u8 prefix 时,浏览器看起来有编码错误。
当我删除 u8
前缀时,浏览器会正确显示。
为什么?
并且我的文档保存为 utf-8(代码页 65001)
带u8
前缀的字符串
不带 u8
前缀的字符串
编辑
更新示例代码
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#pragma comment (lib, "ws2_32.lib")
#define U8
#ifdef U8
typedef const char8_t c;
c str[] = u8"HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=utf-8\r\n\r\n<h1>\xf0\x9f\x93\x9d</h1>";
#else
typedef const char c;
c str[] = "HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=utf-8\r\n\r\n<h1>\xf0\x9f\x93\x9d</h1>";
#endif
template <ULONG N>
constexpr ULONG cstrlen(c(&)[N]) {
return N - 1;
}
int main() {
WSADATA wsaData;
SOCKET listener, s;
CHAR buf[1024 * 3];
WSABUF wsabuf{ .len = sizeof(buf), .buf = buf };
DWORD bytes, flags = 0;
const char* err = "?";
if (WSAStartup(MAKEWORD(2, 2), &wsaData)) {
err = "WSAStartup";
goto Err;
}
{
struct addrinfo hints = {};
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
hints.ai_flags = AI_PASSIVE;
struct addrinfo* result;
if (getaddrinfo(NULL, "80", &hints, &result)) {
err = "getaddrinfo";
goto Err;
}
listener = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_IP, NULL, 0, WSA_FLAG_OVERLAPPED | WSA_FLAG_NO_HANDLE_INHERIT);
if (listener == INVALID_SOCKET) {
freeaddrinfo(result);
err = "WSASocket";
goto Err;
}
if (bind(listener, result->ai_addr, (int)result->ai_addrlen) == SOCKET_ERROR) {
freeaddrinfo(result);
err = "bind";
closesocket(listener);
goto Err;
}
freeaddrinfo(result);
if (listen(listener, SOMAXCONN) == SOCKET_ERROR) {
err = "listen";
closesocket(listener);
goto Err;
}
}
puts("Ready...");
for (;;) {
s = WSAAccept(listener, NULL, NULL, NULL, NULL);
if (s == INVALID_SOCKET) {
closesocket(listener);
err = "WSAAccept";
goto Err;
}
wsabuf.len = sizeof(buf);
wsabuf.buf = buf;
bytes = flags = 0;
if (WSARecv(s, &wsabuf, 1, &bytes, &flags, NULL, NULL) == SOCKET_ERROR) {
err = "WSARecv";
goto Err;
}
wsabuf.buf = (char*)str;
wsabuf.len = cstrlen(str);
if (WSASend(s, &wsabuf, 1, &bytes, 0, NULL, NULL)) {
err = "WSASend";
closesocket(s);
goto Err;
}
closesocket(s);
}
return 0;
Err:
puts(err);
WSACleanup();
return 1;
}
运行 与 std=c++20
感谢@AlanBirtles,使用\u
文字解决了我的问题。
u8
和 u8
都适用于 \U0001f4dd
更新代码
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#pragma comment (lib, "ws2_32.lib")
#define U8
#ifdef U8
typedef const char8_t c;
c str[] = u8"HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=utf-8\r\n\r\n<h1>\U0001f4dd</h1>";
#else
typedef const char c;
c str[] = "HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=utf-8\r\n\r\n<h1>\U0001f4dd</h1>";
#endif const char c;
template <ULONG N>
constexpr ULONG cstrlen(c(&)[N]) {
return N - 1;
}
int main() {
WSADATA wsaData;
SOCKET listener, s;
CHAR buf[1024 * 3];
WSABUF wsabuf{ .len = sizeof(buf), .buf = buf };
DWORD bytes, flags = 0;
const char* err = "?";
if (WSAStartup(MAKEWORD(2, 2), &wsaData)) {
err = "WSAStartup";
goto Err;
}
{
struct addrinfo hints = {};
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
hints.ai_flags = AI_PASSIVE;
struct addrinfo* result;
if (getaddrinfo(NULL, "80", &hints, &result)) {
err = "getaddrinfo";
goto Err;
}
listener = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_IP, NULL, 0, WSA_FLAG_OVERLAPPED | WSA_FLAG_NO_HANDLE_INHERIT);
if (listener == INVALID_SOCKET) {
freeaddrinfo(result);
err = "WSASocket";
goto Err;
}
if (bind(listener, result->ai_addr, (int)result->ai_addrlen) == SOCKET_ERROR) {
freeaddrinfo(result);
err = "bind";
closesocket(listener);
goto Err;
}
freeaddrinfo(result);
if (listen(listener, SOMAXCONN) == SOCKET_ERROR) {
err = "listen";
closesocket(listener);
goto Err;
}
}
puts("Ready...");
for (;;) {
s = WSAAccept(listener, NULL, NULL, NULL, NULL);
if (s == INVALID_SOCKET) {
closesocket(listener);
err = "WSAAccept";
goto Err;
}
wsabuf.len = sizeof(buf);
wsabuf.buf = buf;
bytes = flags = 0;
if (WSARecv(s, &wsabuf, 1, &bytes, &flags, NULL, NULL) == SOCKET_ERROR) {
err = "WSARecv";
goto Err;
}
wsabuf.buf = (char*)str;
wsabuf.len = cstrlen(str);
if (WSASend(s, &wsabuf, 1, &bytes, 0, NULL, NULL)) {
err = "WSASend";
closesocket(s);
goto Err;
}
closesocket(s);
}
return 0;
Err:
puts(err);
WSACleanup();
return 1;
}
我在 visual studio 预览版中编写了一个 HTTP 服务器,我添加 <meta charset="utf-8">
以使用 UTF-8 作为内容编码。
问题是当我在字符串文字上使用 u8 prefix 时,浏览器看起来有编码错误。
当我删除 u8
前缀时,浏览器会正确显示。
为什么?
并且我的文档保存为 utf-8(代码页 65001)
带u8
前缀的字符串
不带 u8
前缀的字符串
编辑
更新示例代码
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#pragma comment (lib, "ws2_32.lib")
#define U8
#ifdef U8
typedef const char8_t c;
c str[] = u8"HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=utf-8\r\n\r\n<h1>\xf0\x9f\x93\x9d</h1>";
#else
typedef const char c;
c str[] = "HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=utf-8\r\n\r\n<h1>\xf0\x9f\x93\x9d</h1>";
#endif
template <ULONG N>
constexpr ULONG cstrlen(c(&)[N]) {
return N - 1;
}
int main() {
WSADATA wsaData;
SOCKET listener, s;
CHAR buf[1024 * 3];
WSABUF wsabuf{ .len = sizeof(buf), .buf = buf };
DWORD bytes, flags = 0;
const char* err = "?";
if (WSAStartup(MAKEWORD(2, 2), &wsaData)) {
err = "WSAStartup";
goto Err;
}
{
struct addrinfo hints = {};
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
hints.ai_flags = AI_PASSIVE;
struct addrinfo* result;
if (getaddrinfo(NULL, "80", &hints, &result)) {
err = "getaddrinfo";
goto Err;
}
listener = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_IP, NULL, 0, WSA_FLAG_OVERLAPPED | WSA_FLAG_NO_HANDLE_INHERIT);
if (listener == INVALID_SOCKET) {
freeaddrinfo(result);
err = "WSASocket";
goto Err;
}
if (bind(listener, result->ai_addr, (int)result->ai_addrlen) == SOCKET_ERROR) {
freeaddrinfo(result);
err = "bind";
closesocket(listener);
goto Err;
}
freeaddrinfo(result);
if (listen(listener, SOMAXCONN) == SOCKET_ERROR) {
err = "listen";
closesocket(listener);
goto Err;
}
}
puts("Ready...");
for (;;) {
s = WSAAccept(listener, NULL, NULL, NULL, NULL);
if (s == INVALID_SOCKET) {
closesocket(listener);
err = "WSAAccept";
goto Err;
}
wsabuf.len = sizeof(buf);
wsabuf.buf = buf;
bytes = flags = 0;
if (WSARecv(s, &wsabuf, 1, &bytes, &flags, NULL, NULL) == SOCKET_ERROR) {
err = "WSARecv";
goto Err;
}
wsabuf.buf = (char*)str;
wsabuf.len = cstrlen(str);
if (WSASend(s, &wsabuf, 1, &bytes, 0, NULL, NULL)) {
err = "WSASend";
closesocket(s);
goto Err;
}
closesocket(s);
}
return 0;
Err:
puts(err);
WSACleanup();
return 1;
}
运行 与 std=c++20
感谢@AlanBirtles,使用\u
文字解决了我的问题。
u8
和 u8
都适用于 \U0001f4dd
更新代码
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#pragma comment (lib, "ws2_32.lib")
#define U8
#ifdef U8
typedef const char8_t c;
c str[] = u8"HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=utf-8\r\n\r\n<h1>\U0001f4dd</h1>";
#else
typedef const char c;
c str[] = "HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=utf-8\r\n\r\n<h1>\U0001f4dd</h1>";
#endif const char c;
template <ULONG N>
constexpr ULONG cstrlen(c(&)[N]) {
return N - 1;
}
int main() {
WSADATA wsaData;
SOCKET listener, s;
CHAR buf[1024 * 3];
WSABUF wsabuf{ .len = sizeof(buf), .buf = buf };
DWORD bytes, flags = 0;
const char* err = "?";
if (WSAStartup(MAKEWORD(2, 2), &wsaData)) {
err = "WSAStartup";
goto Err;
}
{
struct addrinfo hints = {};
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
hints.ai_flags = AI_PASSIVE;
struct addrinfo* result;
if (getaddrinfo(NULL, "80", &hints, &result)) {
err = "getaddrinfo";
goto Err;
}
listener = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_IP, NULL, 0, WSA_FLAG_OVERLAPPED | WSA_FLAG_NO_HANDLE_INHERIT);
if (listener == INVALID_SOCKET) {
freeaddrinfo(result);
err = "WSASocket";
goto Err;
}
if (bind(listener, result->ai_addr, (int)result->ai_addrlen) == SOCKET_ERROR) {
freeaddrinfo(result);
err = "bind";
closesocket(listener);
goto Err;
}
freeaddrinfo(result);
if (listen(listener, SOMAXCONN) == SOCKET_ERROR) {
err = "listen";
closesocket(listener);
goto Err;
}
}
puts("Ready...");
for (;;) {
s = WSAAccept(listener, NULL, NULL, NULL, NULL);
if (s == INVALID_SOCKET) {
closesocket(listener);
err = "WSAAccept";
goto Err;
}
wsabuf.len = sizeof(buf);
wsabuf.buf = buf;
bytes = flags = 0;
if (WSARecv(s, &wsabuf, 1, &bytes, &flags, NULL, NULL) == SOCKET_ERROR) {
err = "WSARecv";
goto Err;
}
wsabuf.buf = (char*)str;
wsabuf.len = cstrlen(str);
if (WSASend(s, &wsabuf, 1, &bytes, 0, NULL, NULL)) {
err = "WSASend";
closesocket(s);
goto Err;
}
closesocket(s);
}
return 0;
Err:
puts(err);
WSACleanup();
return 1;
}