gpt4 book ai didi

c++ - std::ofstream 在\n 之后自动添加回车符 (CR;\r)

转载 作者:行者123 更新时间:2023-11-27 23:54:39 25 4
gpt4 key购买 nike

我正在尝试将 PPM 文件写入磁盘。 PPM 是一种简单的图像格式,由 ASCII 图像标题和像素字节数组组成:

P6\n
width height\n
255\n
[width*height*3 bytes total]

这是我的 PPM 类(简化版):

class PPMImage
{
protected:
friend std::istream& operator >>(std::istream &inputStream, PPMImage &other);
friend std::ostream& operator <<(std::ostream&, const PPMImage&);
size_t width;
size_t height;
// eg. "P6"
std::string magicNumber;
// Normally 255
uint16_t maxBrightness;
std::vector<std::vector<ImagePixel>> pixels;
};

这就是我将图像写入 std::ofstream 的方式:

std::ostream& operator <<(std::ostream &output, const PPMImage &other) {
// Writing header - THIS IS WHERE THE PROBLEM IS!
output<<"P6\n"<<other.width<<'\n'<<other.height<<'\n'<<other.maxBrightness<<'\n';
// The rest is pretty much irrelevant
size_t position = output.tellp();
output.seekp(position+other.width*other.height*3);
// Force the stream to be specific size
const char zero = 200;
output.write(&zero, 1);
// Write the image
output.seekp(position);
for(size_t y=0, yl=other.height; y<yl; ++y) {
for(size_t x=0, xl=other.width; x<xl; ++x) {
output.write((char*)&(other.pixels[y][x].r), 1);
output.write((char*)&(other.pixels[y][x].g), 1);
output.write((char*)&(other.pixels[y][x].b), 1);
}
}
return output;
}

这就是我使用这个 API 的方式:

std::ofstream out;
out.open("copy.ppm");
if(!out.is_open()) {
// error and exit here
}
out<<image;
out.close();

图像看起来没问题,除了 ofstream 在 header 中的每个 \n 之前添加了 \r:

P6\r\n
width height\r\n
255\r\n
[width*height*3 bytes total]

这是 Not Acceptable 。我试图像这样更改初始化代码:

std::ofstream out("copy.ppm", std::ios::binary);
// I wonder why I have to mention "copy.ppm" twice...
out.open("copy.ppm");

但这只会创建空文件。有人可以解释如何在没有回车的情况下正确编写 PPM 吗?

换句话说:如何正确初始化 ofstream 以便它在没有 \r 的情况下写入?

最佳答案

通过错误地再次打开文件,您将流置于失败状态。只需调用 clear() 即可使其工作,但这并不理想。

#include <fstream>
#include <iostream>

class CustomObject{
public:
std::string message;
explicit CustomObject(const std::string &text) : message(text) {}
friend std::ostream& operator <<(std::ostream&, const CustomObject&);
};

std::ostream& operator <<(std::ostream &output, const CustomObject &other) {
if (output.fail()){
std::cout << "the stream is in a fail state due to the bad open" << std::endl;
output.clear();
}

output << "P6\n" << other.message.c_str() << '\n';
return output;
}

int main()
{
std::string filename("something.ppm");
std::ofstream out(filename, std::ios::binary);
out.open(filename);
out << CustomObject("Hello");
}

打开文件的正确方法是将所有参数(文件名和模式)一起传递到您选择放置的任何位置。要么在构造函数中,要么在打开时,但不能同时在两者中。因此,只需使用您的原始代码加上适用于 Windows 的正确模式即可。

std::ofstream out;
out.open("copy.ppm", std::ios::binary);
if(!out.is_open()) {
// error and exit here
}
out<<image;
out.close();

关于c++ - std::ofstream 在\n 之后自动添加回车符 (CR;\r),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43481143/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com