gpt4 book ai didi

c++ - Seekg(ios::beg) 不返回到重定向输入的开头

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:26:55 24 4
gpt4 key购买 nike

我正在制作一个霍夫曼编码器,为此我需要读取输入(它始终是一个重定向文件)以记录频率,然后创建密码本,然后再次读取输入以便我可以对其进行编码.

我的问题是我目前正在尝试测试如何使文件从 cin 读取两次。

我在网上看到 cin.seekg(0) 或 cin.seekg(ios::beg) 或 cin.seekg(0, ios::beg) 只要文件被重定向而不是管道传输,它们都应该可以正常工作.但是当我这样做时,它似乎根本没有对 cin 的位置做任何事情。

这是我目前使用的代码:

#include<iostream>
#include"huffmanNode.h"

using namespace std;

int main(){

//create array that stores each character and it's frequency
unsigned int frequencies[255];
//initialize to zero
for(int i=0; i<255; i++){
frequencies[i] = 0;
}

//get input and increment the frequency of corresponding character
char c;
while(!cin.eof()){
cin.get(c);
frequencies[c]++;
}

//create initial leafe nodes for all characters that have appeared at least once
for(int i=0; i<255; i++){

if(frequencies[i] != 0){
huffmanNode* tempNode = new huffmanNode(i, frequencies[i]);
}
}


// test readout of the frequency list
for(int i=0; i<255; i++){
cout << "Character: " << (char)i << " Frequency: " << frequencies[i] << endl;;
}

//go back to beginning of input
cin.seekg(ios::beg);

//read over input again, incrementing frequencies. Should result in double the amount of frequencies
**THIS IS WHERE IT LOOPS FOREVER**
while(!cin.eof()){
cin.get(c);
frequencies[c]++;
}

//another test readout of the frequency list
for(int i=0; i<255; i++){
cout << "Character: " << (char)i << " Double Frequency: " << frequencies[i] << endl;
}


return 0;
}

调试显示第40行卡在了while循环中,而且好像一直在换行符。为什么它不退出这个循环?我假设 cin.seekg() 实际上并没有重置输入。

最佳答案

您的代码有几个问题。首先是你使用输入 (cin.get( c )) 的结果而不检查输入成功。这总是一个错误;在你的情况下,它会可能只会导致计算(并稍后输出)最后一个字符两次,但它可能导致未定义的行为。你必须在每次输入之前检查输入流是否处于良好状态使用值输入。通常的做法是:

while ( cin.get( c ) ) // ...

,将输入直接放在循环条件中。

第二个是语句:

cin.seekg( std::ios::beg );

我什至有点惊讶这甚至编译:有两个seekg 的重载:

std::istream::seekg( std::streampos );

std::istream::seekg( std::streamoff, std::ios_base::seekdir );

std::ios::beg 的类型为 std::ios_base::seekdir。这是可能的在中定义 std::streamposstd::ios_base::seekdir 的实现一种方法,以便从std::ios_base::seekdirstd::streampos,但在我看来,它不应该,因为结果几乎肯定不是你想要的。寻找文件的开头:

std::cin.seekg( 0, std::ios_base::beg );

第三个问题:输入流中的错误是粘性的。一旦你到达文件末尾,该错误将保留,所有其他在您清除错误之前,操作将是空操作:std::cin.clear();.

最后一条评论:您正在使用 std::cin 这一事实让我很担心。它可能会起作用(尽管不能保证您可以寻求在 std::cin 上,即使输入是从文件重定向的),但确实知道没有可以输出霍夫曼结果的方法编码为 std::cout。它可以在 Unix 下工作,但可能不在任何地方别的。霍夫曼编码要求文件以二进制模式打开,std::cinstd::cout 从来不是这种情况。

关于c++ - Seekg(ios::beg) 不返回到重定向输入的开头,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17902156/

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