4

现在我正在使用 istream 读取数据。我有我想作为字符串和数字读入的文本,以及读入字符数组的哈希值。由于哈希实际上是随机的,因此当我尝试将其读回并点击 EOF(这是哈希的一部分)时,我遇到了障碍。有没有办法在不诉诸 fread 的情况下做到这一点。另外,是否可以同时使用 istream 和 fread 一些我不必手动解析整数和字符串。最后,使用 fgets 获取未知长度的字符串的最佳方法是什么。

谢谢,埃里克

编辑:这是代码:

string dummy;
ifstream in(fileName);
for(int i=0; i<numVals; i++)
{
    int hashLen;
    in>>hashLen;
    char cc;
    in.get(cc);//Get the space in between
    cout<<"Got first byte: "<<(int)cc<<endl;

    char * hashChars = new char[hashLen];
    in.read(hashChars, hashLen);
    for(int j =0; j <hashLen; j++)
    {
        char c = hashChars[j];
       unsigned char cc = reinterpret_cast<unsigned char&>(c);
        cout<<"Got byte: "<<(int)c<<(int)cc<<endl;
        if(in.fail())
        {
            cout<<"Failed! "<<in.eof()<<" "<<in.bad()<<endl;
        }
    }

delete hashChars;

    getline(in,dummy);//get a dummy line
    cout<<"Dummy: "<<dummy<<" numvals: "<<numVals<<" i: "<<i<<" hashLength: "<<hashLen<<endl;
}

我的输出看起来像:

1>得到第一个字节:32

1>得到字节:4 4

1>得到字节:-14 242

1>得到字节:108 108

1>得到字节:87 87

1>得到字节:113 113

1>得到字节:-116 140

1>得到字节:-106 150

1>得到字节:-35 221

1>得到字节:0 0

1>得到字节:-91 165

1>得到字节:39 39

1>得到字节:111 111

1>得到字节:7 7

1>得到字节:126 126

1>得到字节:16 16

1>得到字节:-42 214

1>虚拟:numvals:35 i:12 hashLength:16

1>得到第一个字节:32

1>得到字节:14 14

1>失败!1 0

1>得到字节:-65 191

1>失败!1 0

1>得到字节:-107 149

1>失败!1 0

1>得到字节:-44 212

1>失败!1 0

1>得到字节:-60 196

1>失败!1 0

1>得到字节:-51 205

1>失败!1 0

1>得到字节:-51 205

1>失败!1 0

4

1 回答 1

2

读取二进制数据时,您通常希望std::ifstream使用 flag打开std::ios_base::binary。由此产生的差异相当小,但它们通常很重要。

您可能需要修复代码中的一些奇怪之处:

  • 总是需要在阅读后检查操作是否成功,例如,使用if (in.read(hashChars, hashLen)) { ... }
  • 无需使用reinterpret_cast<...>()始终具有实现定义的语义。你应该static_cast<unsigned char>(c)改用。
  • 您分配了一个字符数组,但您使用delete p. 你需要delete[] p改用。使用delete p会导致未定义的行为。但是,实际上根本不需要使用newand delete,就像std::vector<char> hashChars(hashLen)自动内存管理一样。

上面的请求中嵌入了一些[残缺的]问题(因此问题/答案是对所问内容的猜测):

  • 你能在同一个流上混合std::istream::read()和吗fread()(我想这是问题):除非流恰好是std::cin从与stdin. 如果您想在同一个文件上同时使用两者std::istream::read()fread()则需要FILE*用合适的 a包装 a 并用相应的对象std::streambuf初始化 a 。std::istream
  • 如何读取任意大小的行fgets()?你不能。要在尝试填充之前分配的缓冲区,fgets()并且始终可以在到达换行符之前填充。但是,您可以使用std::getline()读取任意长行。如果你只是想跳过这一行,你可以在使用in.ignore(std::numeric_limits<std::streamsize>::max(), '\n')时使用std::istream. 副手不知道有没有类似的操作FILE*
于 2013-08-17T00:46:24.483 回答