标签: fstream

使用C++编写二进制文件:默认语言环境是否重要?

我有使用fstream操作二进制文件的代码,其中设置了二进制标志并使用未格式化的I/O函数进行读写.这在我曾经使用的所有系统上都能正常工作(文件中的位完全符合预期),但这些基本上都是美国英语.我一直在想这些字节是否可能被不同系统上的codecvt修改.

听起来像标准说使用无格式I/O的行为与使用sputc/sgetc将字符放入streambuf相同.这些将导致streambuf中的溢出或下溢函数被调用,并且听起来这些函数会导致某些代码转换(例如,参见c ++标准中的27.8.1.4.3).对于basic_filebuf,此编解码器的创建在27.8.1.1.5中指定.这使得结果看起来将取决于basic_filebuf.getloc()返回的内容.

所以,我的问题是,我可以假设在一个系统上使用ofstream.write写出的字符数组可以使用ifstream.read在另一个系统上逐字恢复,无论人们在他们的系统上使用哪种语言环境配置?我会做出以下假设:

  1. 该程序使用默认语言环境(即程序本身根本不更改语言环境设置).
  2. 系统都有CHAR_BIT 8,每个字节内的位顺序相同,存储文件为八位字节等.
  3. 流对象具有二进制标志集.
  4. 在此阶段,我们无需担心任何字节差异.如果要将数组中的任何字节解释为多字节值,则将在稍后阶段根据需要处理字节序转换.

如果无法保证默认语言环境在某些系统配置(我不知道,阿拉伯语或其他东西)上未经修改的情况下通过这些内容,那么使用C++编写二进制文件的最佳方法是什么?

c++ binary locale fstream

8
推荐指数
1
解决办法
811
查看次数

如何从fstream精确地读取128个字节到字符串对象?

如何从fstream到字符串对象中准确读取128个字节?

我写了一些代码来读取文件的前128个字节并打印它然后打印文件的最后128个字节并打印出来.最后一部分可以工作,因为您可以轻松地迭代到EOF,但是如何从前面获得正好128个字节?下面的代码不起作用,因为你不能添加128到ifstream的迭代器,它不是可转位,仅可递增的(似乎).

当然我可以制作一个迭代器和*++它128次,但必须有一条直线的方法来做,对吧?

#include <iostream>
#include <fstream>
#include <string>

int main(int argc, char **argv)
{
    std::ifstream ifs ("input.txt",std::ifstream::in | std::ifstream::binary);

    if (ifs.good())
    {
    // read first 128 bytes into a string
        ifs.seekg(0,std::ifstream::beg);
        std::string first128((std::istreambuf_iterator<char>(ifs)),
                             (std::istreambuf_iterator<char>(ifs))+128);

        std::cout << first128 << std::endl;

    // read last 128 bytes into a string
        ifs.seekg(-128,std::ifstream::end);
        std::string last128((std::istreambuf_iterator<char>(ifs)),
                            std::istreambuf_iterator<char>());

        std::cout << last128 << std::endl;

        return 0;
    }

    return 1;
}
Run Code Online (Sandbox Code Playgroud)

c++ string fstream iostream ifstream

8
推荐指数
1
解决办法
1万
查看次数

写入二进制文件

#include <iostream>
#include <fstream>

using namespace std;

class info {

private:
    char name[15];
    char surname[15];
    int age;
public:
    void input(){
        cout<<"Your name:"<<endl;
            cin.getline(name,15);
        cout<<"Your surname:"<<endl;
        cin.getline(surname,15);
        cout<<"Your age:"<<endl;
        cin>>age;
        to_file(name,surname,age);
    }

    void to_file(char name[15], char surname[15], int age){
        fstream File ("example.bin", ios::out  | ios::binary | ios::app);
    // I doesn't know how to fill all variables(name,surname,age) in 1 variable (memblock) 
        //example File.write ( memory_block, size ); 

File.close();
    }

};

int main(){

info ob;
ob.input();

 return 0;
}
Run Code Online (Sandbox Code Playgroud)

我不知道如何将1个以上的变量写入文件,请帮助,我包含了一个例子;)也许有更好的方法来写一个文件,请帮我这个,这对我来说很难解决.

c++ binary fstream

8
推荐指数
2
解决办法
3万
查看次数

在AIX上使用ofstream

我试图在AIX Box上编写一个简单的C++程序.该计划如下:

# include <iostream>
# include <fstream>
using namespace std ;


int main()
{
    ofstream of ;
    of.open("license.txt") ;
    of<<"hello"<<endl ;
    of.close() ;
}
Run Code Online (Sandbox Code Playgroud)

我的LDFLAGS设置如下:

-maix64 -L/disk3/TOOLS/GCCTools/gcc-4.5.1/lib/ppc64 \
-L/disk3/TOOLS/GCCTools/gcc-4.5.1/lib/gcc/powerpc-ibm-aix6.1.0.0/4.5.1/ppc64 \
-L/disk3/TOOLS/GCCTools/gcc-4.5.1/lib/gcc/powerpc-ibm-aix6.1.0.0/4.5.1 \
-L/disk3/TOOLS/OPENSSL/lib
Run Code Online (Sandbox Code Playgroud)

CFLAGS是:

-O2 -maix64 -I/disk3/TOOLS/OPENSSL/include -D_ALL_SOURCE -D_XOPEN_SOURCE \
-D_XOPEN_SOURCE_EXTENDED -DSS_64BIT_SERVER -D_POSIX_SOURCE -D__64BIT__ \
-I/disk3/TOOLS/OPENSSL/include -I/usr/include \
-I/disk3/TOOLS/GCCTools/gcc-4.5.1/lib/gcc/powerpc-ibm-aix6.1.0.0/4.5.1/include
Run Code Online (Sandbox Code Playgroud)

该程序编译良好.但是当我尝试运行相同的程序时,程序出现了分段错误.我使用gdb运行相同的操作,并在使用ofstream时发现以下问题:

Program received signal SIGSEGV, Segmentation fault.
0x09000000036107c4 in std::locale::operator=(std::locale const&) (this=
findvar.c:706: internal-error: value_from_register: Value not stored anywhere!
Run Code Online (Sandbox Code Playgroud)

对于为什么会发生这种情况的任何想法?任何帮助表示赞赏:)

注意:fstream本身就有用......

c++ aix fstream

8
推荐指数
1
解决办法
954
查看次数

从fstream中读取单个字符?

我正试图从stdio转移到iostream,这证明非常困难.我已经掌握了加载文件并关闭文件的基础知识,但我真的不知道什么是流甚至是什么,或者它们是如何工作的.

在stdio中,与此相比,一切都相对容易和直接.我需要做的是

  1. 从文本文件中读取单个字符.
  2. 根据该角色调用函数.
  3. 重复,直到我读完文件中的所有字符.

到目前为止我所拥有的......并不多:

int main()
{
    std::ifstream("sometextfile.txt", std::ios::in);
    // this is SUPPOSED to be the while loop for reading.  I got here and realized I have 
    //no idea how to even read a file
    while()
    {
    }
return 0;
}
Run Code Online (Sandbox Code Playgroud)

我需要知道的是如何获得单个字符以及该字符实际存储的方式(它是一个字符串吗?一个int?一个char?我可以自己决定如何存储它吗?)

一旦我知道我认为我可以处理其余的事情.我将角色存储在适当的容器中,然后使用开关根据角色的实际情况做事.它看起来像这样.

int main()
{
    std::ifstream textFile("sometextfile.txt", std::ios::in);

    while(..able to read?)
    {
        char/int/string readItem;
        //this is where the fstream would get the character and I assume stick it into readItem?
        switch(readItem)
        {
        case 1:
            //dosomething
              break;
        case …
Run Code Online (Sandbox Code Playgroud)

c++ file-io fstream iostream

8
推荐指数
2
解决办法
2万
查看次数

由于memcpy,C++ ifstream :: read很慢

最近我决定优化我正在做的一些文件读取,因为正如大家所说,将大量数据读取到缓冲区然后使用它比使用大量小读取更快.而且我的代码现在肯定要快得多,但在进行一些分析之后,似乎memcpy占用了大量的时间.

我的代码的要点是......

ifstream file("some huge file");
char buffer[0x1000000];
for (yada yada) {
    int size = some arbitrary size usually around a megabyte;
    file.read(buffer, size);
    //Do stuff with buffer
}
Run Code Online (Sandbox Code Playgroud)

我正在使用Visual Studio 11,在对我的代码进行分析后,它ifstream::read()最终会调用xsgetn()从内部缓冲区到我的缓冲区的副本.此操作占用超过80%的时间!排在第二位的是uflow()10%的时间.

有什么方法可以绕过这个复制吗?我可以以某种方式告诉我ifstream将我需要的大小缓冲到我的缓冲区吗?C风格FILE*也使用这样的内部缓冲区吗?

更新:由于人们告诉我使用cstdio ...我做了一个基准测试.

编辑:不幸的是旧的代码充满了失败(它甚至没有读取整个文件!).你可以在这里看到它:http://pastebin.com/4dGEQ6S7

这是我的新基准:

const int MAX = 0x10000;
char buf[MAX];
string fpath = "largefile";
int main() {
    {
        clock_t start = clock();
        ifstream file(fpath, ios::binary);
        while (!file.eof()) {
            file.read(buf, MAX);
        }
        clock_t end …
Run Code Online (Sandbox Code Playgroud)

c++ performance fstream memcpy visual-c++

8
推荐指数
2
解决办法
5617
查看次数

访问文件中的单个字符效率低下?(C++)

在处理文本文件时,我总是认为它更高效,首先将内容(或部分内容)读入std :: string或char数组,因为 - 从我有限的理解 - 文件从内存中读取块大于单个字符的大小.但是,我听说现代操作系统通常不会直接从文件中读取,这使得我手动缓冲输入的好处不大.

假设我想确定文本文件中某个字符的编号.以下是否会效率低下?

while (fin.get(ch)) {
    if (ch == 'n')
        ++char_count;
}
Run Code Online (Sandbox Code Playgroud)

当然,我想这取决于文件大小,但是有没有人对什么是最好的方法有任何一般规则?

c++ file-io fstream

8
推荐指数
2
解决办法
1072
查看次数

为模拟的std :: fstream类避免"优势继承"警告

我正在使用googlemockstd::fstream在我的单元测试中模拟出一个对象,如下所示:

TEST_F(SomeTest, SomethingIsDoneCorrectly)
{
    class MockFstream : public std::fstream {};
    MockFstream lMockFstream;
    // Expectations and assertions here
}
Run Code Online (Sandbox Code Playgroud)

当我编译时,我得到以下警告:

警告1警告C4250:'SomeTest_SomethingIsDoneCorrectly_Test :: TestBody :: MockFstream':通过优势继承'std :: basic_istream <_Elem,_Traits> :: std :: basic_istream <_Elem,_Traits> :: _ Add_vtordisp1'

警告2警告C4250:'SomeTest_SomethingIsDoneCorrectly_Test :: TestBody :: MockFstream':通过优势继承'std :: basic_ostream <_Elem,_Traits> :: std :: basic_ostream <_Elem,_Traits> :: _ Add_vtordisp2'

我更喜欢干净的构建输出,所以我想要抑制这些特定的警告,但我正在编写跨平台代码,所以我也更愿意避免使用特定于编译器的#pragmas.

我可以在googlemock对象中做些什么来隐藏这些警告吗?

c++ fstream mocking compiler-warnings visual-c++

8
推荐指数
1
解决办法
1539
查看次数

带有std :: ate的std :: ofstream最后没有打开

我正在尝试打开一个文件输出并附加到它.在附加到它之后,我想将输出位置移动到文件中的其他位置并覆盖现有数据.据我了解,std::ios_base::app强制所有写入都在文件的末尾,这不是我想要做的.因此,我认为std::ios_base::ate是传递给它的正确旗帜std::ofstream::open().但是,似乎没有按预期工作:

// g++ test.cpp
// clang++ test.cpp
// with and without -std=c++11
#include <iostream>
#include <fstream>

int main() {
    std::streampos fin, at;
    {
        std::ofstream initial;
        initial.open("test", std::ios_base::out | std::ios_base::binary);
        if ( not initial.good() ) {
            std::cerr << "initial bad open" << std::endl;
            return 1;
        }
        int b = 100;
        initial.write((char*)&b, sizeof(b));
        initial.flush();
        if ( not initial.good() ) {
            std::cerr << "initial write bad" << std::endl;
            return 1;
        } …
Run Code Online (Sandbox Code Playgroud)

c++ fstream c++11

8
推荐指数
1
解决办法
1735
查看次数

如何用C++写入文件的中间?

我认为这应该很简单,但到目前为止我的谷歌搜索没有帮助...我需要用C++写入现有文件,但不一定在文件的末尾.

我知道当我只想将文本附加到我的文件时,我可以ios:app在调用open我的流对象时传递该标志.但是,这只是让我写到文件的最后,而不是写到它的中间.

我做了一个简短的程序来说明这个问题:

#include <iostream>
#include <fstream>

using namespace std;

int main () {

  string path = "../test.csv";

  fstream file;
  file.open(path); // ios::in and ios::out by default

  const int rows = 100;
  for (int i = 0; i < rows; i++) {
    file << i << "\n";
  }  

  string line;
  while (getline(file, line)) {
    cout << "line: " << line << endl; // here I would like to append more text to certain rows
  }


  file.close(); …
Run Code Online (Sandbox Code Playgroud)

c++ fstream ifstream ofstream

8
推荐指数
2
解决办法
9956
查看次数