从C

时间:2018-01-13 14:04:33

标签: c unicode

我正在尝试从.pas文件中读取pascal代码并逐行在控制台中写入。那部分工作正常。现在我想在我正在阅读的.pas文件中添加土耳其语字符并显示它。 我已经包括了

#include <locale.h> 

setlocale(LC_ALL, "Turkish");

当我写Şperator包含土耳其语而不是操作员程序打印出Å?perator。我希望它打印出来Şperator。什么问题?

Pascal code

这是完整的代码

#include <stdio.h>
#include <conio.h>
#include <locale.h> 
#include <sys/types.h>
#include <sys/timeb.h>
#include <string.h>
#include <unistd.h>
#include <wchar.h>



#define FORM_FEED_CHAR    '\f'

#define MAX_FILE_NAME_LENGTH    32
#define MAX_SOURCE_LINE_LENGTH  256
#define MAX_PRINT_LINE_LENGTH   120
#define MAX_LINES_PER_PAGE      50
#define DATE_STRING_LENGTH      26

typedef enum {
    FALSE, TRUE,
}BOOLEAN;

int line_number = 0;
int page_number = 0;
int level = 0;
int line_count = MAX_LINES_PER_PAGE;

char source_buffer[MAX_SOURCE_LINE_LENGTH];

char source_name[MAX_FILE_NAME_LENGTH];
char date[DATE_STRING_LENGTH];

FILE*source_file;

main(argc, argv)
int argc;
char *argv[];
{
    setlocale(LC_ALL, "Turkish");
    BOOLEAN get_source_line();

    init_lister("C:/Users/Dzenan/Documents/calculator1.pas");
    while (get_source_line());
}

init_lister(name)
char *name;
{
    time_t timer;
    strcpy(source_name, name);
    source_file = fopen(source_name, "r");

    time(&timer);
    strcpy(date, "d");
}

BOOLEAN
get_source_line()
{
    char print_buffer[MAX_SOURCE_LINE_LENGTH + 9];
    if ((fgets(source_buffer, MAX_SOURCE_LINE_LENGTH,
            source_file)) != NULL) {
        ++line_number;
        sprintf(print_buffer, "%4d %d: %s",
            line_number, level, source_buffer);
        print_line(print_buffer);
        return(TRUE);
    }
    else return(FALSE);
}

print_line(line)
char line[];
{
    char save_ch;
    char *save_chp = NULL;

    if (++line_count > MAX_LINES_PER_PAGE) {
        print_page_header();
        line_count = 1;
    };

    if (strlen(line)> MAX_PRINT_LINE_LENGTH)
    save_chp = &line[MAX_PRINT_LINE_LENGTH];

    if(save_chp){
        save_ch = *save_chp;
        *save_chp = '\0';
    }

    printf("%s", line);

    if(save_chp) *save_chp = save_ch;

}

print_page_header() {
    putchar(FORM_FEED_CHAR);
    printf("Page %d  %s  %s\n\n", ++page_number, source_name, date);
}

2 个答案:

答案 0 :(得分:1)

这不是您的问题 - 您只需要正确配置终端模拟器(cmd.exe)编码。 C字符串没有编码。它们只是字节序列。您的程序会准确打印文件中可能以UTF-8编码的内容。

答案 1 :(得分:0)

setlocale只会更改ANSI代码页。它与Unicode不同。如果文件保存在土耳其语代码页中,您的代码将起作用。检查文件代码页以确保。

要在Windows控制台中打印Unicode,请使用UTF-16。例如:

#include <Windows.h>
...
HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE);
const wchar_t *wstr = L"Şperator\n";
DWORD temp;
WriteConsoleW(h, wstr, wcslen(wstr), &temp, 0);

如果源文件是UTF-8,请使用以下代码。请注意,该文件以二进制模式打开。如果源文件是土耳其语代码页,请使用CP_ACP或土耳其语代码页而不是CP_UTF8。在不太可能的情况下,代码页为UTF-16,请跳过MultiByteToWideChar转换

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

int main(void)
{
    HANDLE h = GetStdHandle(STD_OUTPUT_HANDLE);
    DWORD temp;

    FILE *fp = fopen("utf8.txt", "rb");
    fseek(fp, 0, SEEK_END);
    size_t filesize = ftell(fp);
    fseek(fp, 0, SEEK_SET);
    char *buf = malloc(filesize + 1);
    fread(buf, 1, filesize, fp);
    buf[filesize] = 0;

    int widesize = MultiByteToWideChar(CP_UTF8, 0, buf, -1, 0, 0);
    wchar_t *wbuf = malloc(widesize * 2);
    MultiByteToWideChar(CP_UTF8, 0, buf, -1, wbuf, widesize);
    WriteConsoleW(h, wbuf, widesize, &temp, 0);

    free(buf);
    free(wbuf);

    fclose(fp);

    return 0;
}