2013-04-28 24 views
0

我正在尝试编写一些代码来读取文件并提取它的位并将它们保存为变量。任何方式摆脱istream结束时的空字符得到?

下面是相关代码:

char address[10]; 

ifstream tracefile; 
tracefile.open ("trace.txt"); 
tracefile.seekg(2, ios::beg); 
tracefile.get(address, 10, ' '); 
cout << address; 

文件的内容:(只第一行)

R 0x00000000 

我遇到的问题是地址错过最后的“0”因为它在那里放了一个/ 0字符,我不知道如何解决这个问题?因此它输出:

tracefile.seekg(2, ios::cur); 

它似乎没有工作,因此为什么我把它改为IOS ::求只是为了尝试并获得

0x0000000 

我也有问题一些工作,虽然显然,一旦我尝试读取多行后,将无法使用。

任何帮助,将不胜感激。

+0

如何使用拆分字符串? http://stackoverflow.com/questions/236129/splitting-a-string-in-c – user1732445 2013-04-28 16:04:58

+0

使数组大小11个 – Praetorian 2013-04-28 16:06:06

回答

0

使缓冲区更大,以便您可以读入整个输入文本,包括终止'\0'。或使用std::string,它没有预先确定的大小。

+0

谢谢,我没有做到这一点,但随后介绍了与下位的问题我需要编写代码,将地址与数组中的条目进行比较(我正在编码缓存模拟器),因为会有一个额外的字符,我不想要,我应该提到在OP 。 – GeorgeStorm 2013-04-28 16:16:38

+0

读入C风格的文本缓冲区在输入末尾放置一个“\ 0”。这就是C字符串的工作原理。如果你对“\ 0”后缀不感兴趣,可以忽略它。 – 2013-04-28 16:19:44

+0

@ user2329442为什么它会导致地址比较问题。你有一个字符串。根据定义,C风格的字符串是以''\ 0''结尾的;如果没有''\ 0'',你会对你的变量做任何事情都会有非常严重的问题(即像'strcmp'这样的函数将不起作用)。 – 2013-04-28 16:22:55

3

ifstream::get()将尝试产生一个以空字符结尾的C字符串,但您尚未提供足够的空间。

您可以:

  1. 分配char address[11];(或更大)持有空终止字符串,长度超过9个字符。
  2. 改为使用ifstream::read()来读取没有空终止符的10个字节。

编辑:

如果你想有一个缓冲区,可以动态占线路长度,使用std::getlinestd::string

std::string buffer; 
tracefile.seekg(2, ios::beg); 
std::getline(tracefile, buffer); 

编辑2

如果你只想读下一个空格,使用:

std::string buffer; 
tracefile.seekg(2, ios::beg); 
tracefile >> buffer; 
+0

正如我对皮特说,它放大解决了这个问题,但我认为会介绍他人:( 我会看看:: ifstream的阅读()谢谢:) – GeorgeStorm 2013-04-28 16:16:57

+1

@ user2329442 _not_提供尾随'“\ 0”如果你把它当作一个字符串来处理,会给下游带来更多的问题。如果你想把输入视为一个字符串(显然你这么做了,因为这就是'char []'通常意义上的意思),那么你必须确保最后还有一个额外的'''0' _或_使用'std :: string'(通常是首选的解决方案)。 – 2013-04-28 16:25:45

+0

目标是让程序读取地址,检查缓存是否包含该地址的数据,如果是,则读取它,如果不是,则转到主内存并将其复制到缓存中(缓存和主内存是数组)。所以'地址'将与'cache'数组中每个条目的地址变量进行比较。 我很快尝试使地址字符串而不是char [],但后来读/不喜欢它? – GeorgeStorm 2013-04-28 16:33:24

0

有你的代码的几个问题。首先是 seekg(2, ios::beg)是未定义的行为,除非在二进制模式下打开流 (不是你的)。它将在Unix下工作 ,并根据文件的内容,它 可能在Windows下工作(但它也可能会将您发送到 错误的地方)。在其他一些系统上,它可能会系统地失败,或者做其他任何事情。您无法可靠地将 查找到文本流中的任意位置。

第二个是,如果你想读的正好10个字符, 你需要的功能是istream::read,而不是 istream::get。另一方面,如果您想读取 下一个空格,将>>转换为字符串将效果最佳。 如果你想打电话>>之前限制提取到最大 的字符数,设置宽度:

std::string address; 
// ... 
tracefile >> std::setw(10) >> address; 

这样就避免了'\0'所有问题,等等

最后,当然,你需要错误检查。你应该 可能检查是否开放做任何其他 之前成功了,你一定要检查使用结果之前读取是否成功 。 (正如你所编写的代码,如果 打开的任何原因而失败,你有不确定的行为。)

如果你正在读多行,当然,最好的解决办法 通常是使用std::getline阅读每行成 字符串,然后解析该字符串(可能使用 std::istringstream)。这防止 进入错误状态的主要流如果在线路的格式错误,以及 它在这样的情况下提供自动再同步。