【问题标题】:Why does ifstream read() behave differently in two different programs?为什么 ifstream read() 在两个不同的程序中表现不同?
【发布时间】:2016-07-24 00:10:40
【问题描述】:

我正在尝试编写一个从 .txt 文件中读取 OpenGL 着色器的程序。实际上我几天前已经这样做了,这是我使用的代码:

char vShaderData[2000];
char fShaderData[2000];
void readShaders() {
    std::ifstream vShaderF;
    std::ifstream fShaderF;
    vShaderF.open("shaders//vertexShader.txt");
    fShaderF.open("shaders//fragShader.txt");
    if (vShaderF.is_open() && fShaderF.is_open()) std::cout << m << "Shader read success" << std::endl; 
    else std::cout << "Shader read fail" << std::endl; 
    std::cout << m << "vertex shader: " << std::endl;
    vShaderF.read(vShaderData, 2000);
    for (int i = 0; i < 2000; i++) {
        std::cout << vShaderData[i];
    }
    std::cout << std::endl << std::endl;
    std::cout << m << "frag shader: " << std::endl;
    fShaderF.read(fShaderData, 2000);
    for (int i = 0; i < 2000; i++) {
        std::cout << fShaderData[i];
    }
    std::cout << std::endl;
    vShaderF.close();
    fShaderF.close();
}

这很好用。我的着色器文件的长度实际上不是 2000,但 read() 调用似乎将多余的字符作为空格存储到我想要的 char 数组中。

现在在一个新程序中对我的代码进行了一些重组,我的阅读器现在看起来像这样:

    std::ifstream shaderFile;
    shaderFile.open(path);  
    if (shaderFile.is_open()) cout << "Shader at: " << path << ", initalized" << endl;
    char data[2000];
    shaderFile.read(data, 2000);

    for (int i = 0; i < 2000; i++) std::cout << data[i];    

实际的文本部分仍然正确。但是,现在 char 数组中的额外空间是用这个而不是空格存储的:

万一图片不显示,基本上就是这两个字符[|[|[|...的重复模式。

为什么会发生这种情况,我该如何解决?

注意:我使用的是相同的着色器文件、相同的计算机、相同的 IDE,所有内容都相同。旧的仍然有效。

【问题讨论】:

  • 嗯,不同之处在于全局数组的初始化方式与本地分配的方式。
  • @πάνταῥεῖ 啊,是的。我刚刚将我的数组更改为全局数组,它填充了空格。谢谢你。对不起,这么愚蠢和简单的问题,我不太了解 C++。我主要做java,
  • 在 C/C++ 中,标量类型的实例化不会初始化它(性能原因),因此在函数中执行 int a; 意味着,a 可以有任何值(堆栈上有什么)。全局变量是例外,初始化为类型默认值(对于int,它是0)。在 Java 中,您将始终收到所有内容的初始化实例(这就是为什么 Java 与正确编写的 C/C++ 相比速度慢的原因 #1234345,这在现实生活中无关紧要,因为几乎没有人知道编写正确的 C/C++(至少我不知道) 't))
  • @Ped7g 不,你是正确的:几乎没有人知道如何编写正确的 C xD。这就是我坚持使用高级语言的原因。 C 和 Assembly 吓坏了我!
  • 别怕Assembly,不是1985,显卡控制寄存器不小心输出错误频率会烧屏。今天它基本上是无害的,并且操作系统得到了很好的保护。你不会相信我在 ZX 上丢失了多少次我的源代码,因为我在尝试之前忘记将它保存到磁带上(没有忘记那么多,因为我非常确定这次它会工作,无需重置 ZX,我只是懒得等那些 15-20 岁来保存它)。现在一切都变得轻而易举,有了可用的调试器和虚拟机等……我不得不在纸上进行大部分调试。

标签: c++ file-io ifstream


【解决方案1】:

当使用std::istream:read() 时,它将将缓冲区的部分设置为未读取的空间。记忆将不受影响。如果要将空格放入缓冲区的未读区域,则需要自己将空格放在那里。如果程序确实在缓冲区中有空格,那是因为缓冲区偶然已经包含了空格。

您可以使用std::istream::gcount() 来确定读取了多少个字符。

【讨论】:

    【解决方案2】:

    如果您希望数组包含预定义数据,则必须使用此类预定义数据对其进行初始化。如果流读取的数据少于数组大小,您将获得所需的填充。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-05-12
      • 1970-01-01
      • 1970-01-01
      • 2015-12-13
      • 1970-01-01
      • 2016-06-02
      • 2022-11-30
      相关资源
      最近更新 更多