Использование одного и того же объекта для записи широких символов и символов для записи в один и тот же файл - PullRequest
1 голос
/ 15 апреля 2019

У меня есть код C, который я пытаюсь преобразовать в C ++.Подводя итог, фрагмент кода в C выглядит следующим образом:

    FILE *fp = fopen("temp.bin", "wb");
    wchar_t* wide_word = _T("wide char");
    char* word = "char";
    fwprintf(fp, _T("%s"), wide_word);
    fprintf(fp, "%s", word);

Преимущество в случае C состоит в том, что мы можем продолжать использовать один и тот же указатель fp для печати как char, так и wide char, просто передав указатель.Можем ли мы достичь того же в C ++ без необходимости инициализировать объекты ofstream и wofstream для записи в тот же файл и получить точно такой же вывод, как в описанной выше реализации C?

Я пробовал следующее в C ++ (среди многих других вещей)

    auto os = std::ofstream("temp_cpp.bin", std::ios::binary | std::ios::out);
    wchar_t* wide_word = _T("wide char");
    char* word = "char";
    std::wstring st(wide_word);
    std::string str(st.begin(),st.end());
    os.write(reinterpret_cast<const char*>(str.c_str()), sizeof(str));
    os.write(reinterpret_cast<const char*>(word), sizeof(word));

1 Ответ

2 голосов
/ 16 апреля 2019

Да, вы можете использовать одну и ту же функцию write для записи байтов ANSI или широких байтов в файл. В коде есть некоторые ошибки. sizeof(str) вернет размер объекта std::string, а не длину строки, а sizeof(word) вернет размер указателя, опять же не длину строки (хотя вам может повезти с этим на 32 -битные системы, где размер указателя соответствует длине строки). Кроме того, вы пишете символы ANSI два раза, а не сначала пишете широкие символы, а затем символы ANSI, как вы, вероятно, и предполагали, следуя своему примеру fprintf. Вероятно, вы хотели написать:

auto os = std::ofstream("temp_cpp.bin", std::ios::binary | std::ios::out);
const wchar_t* wide_word = L"wide char";
const char* word = "char";
std::wstring st(wide_word);
std::string str(st.begin(), st.end());
os.write((const char*)(st.c_str()), st.length() * sizeof(wchar_t));
os.write(word, strlen(word));

Это должно привести к тому же содержимому файла, что и ваш fprintf пример (но это не гарантируется, так как может зависеть от setLocale). Или без использования std::wstring:

auto os = std::ofstream("temp_cpp.bin", std::ios::binary | std::ios::out);
const wchar_t* wide_word = L"wide char";
const char* word = "char";
os.write((const char*)wide_word, wcslen(wide_word) * sizeof(wchar_t));
os.write(word, strlen(word));

Желательно ли записывать разные кодировки текста в один и тот же файл - это другой вопрос.

...