C++ cin 数字忽略第一行?

发布于 2024-10-03 19:20:04 字数 1381 浏览 5 评论 0原文

我遇到了一个非常奇怪的问题。我可以在我的 win7 笔记本电脑和 ubuntu 机器上重现。

我有一个像这样的 C++ 程序:

#include <string>
#include <sstream>
#include <iostream>
using namespace std;

int main() {
  for (int i = 0; i < 9; i++) {
    string line;
    getline(cin, line);
    stringstream ss(line);

    for (int j = 0; j < 9; j++) {
      int p = 8;
      ss >> p;
      cout << p;
    }
    cout << endl;
  }
  return 0;
}

现在,如果我编译它并使用 ./a.out 运行它。 test.txt 其中 text.txt 包含:

1 2 3 4 5 6 7 8 9
2 2 3 4 5 6 7 8 9
3 2 3 4 5 6 7 8 9
4 2 3 4 5 6 7 8 9
5 2 3 4 5 6 7 8 9
6 2 3 4 5 6 7 8 9
7 2 3 4 5 6 7 8 9
8 2 3 4 5 6 7 8 9
9 2 3 4 5 6 7 8 9

它将输出(不带空格):

8 8 8 8 8 8 8 8 8
2 2 3 4 5 6 7 8 9
3 2 3 4 5 6 7 8 9
4 2 3 4 5 6 7 8 9
5 2 3 4 5 6 7 8 9
6 2 3 4 5 6 7 8 9
7 2 3 4 5 6 7 8 9
8 2 3 4 5 6 7 8 9
9 2 3 4 5 6 7 8 9

为什么第一行错误?我也尝试过从循环中读取第一行。 另外,如果我替换 ss > pcin > p 我刚刚得到一个满是 8 的输出表。

这没有任何意义!

好吧,你们是对的。我的输入文件的第一个字符有一些奇怪的东西:

od -c test.txt
0000000 357 273 277   2       0       5       0       0       7       0
0000020       0       6  \n   4       0       0       9       6       0
0000040       0       2       0  \n   0       0       0       0       8

I've run into a really strange issue. I can reproduce on my win7 laptop as well as an ubuntu machine.

I have a C++ program like so:

#include <string>
#include <sstream>
#include <iostream>
using namespace std;

int main() {
  for (int i = 0; i < 9; i++) {
    string line;
    getline(cin, line);
    stringstream ss(line);

    for (int j = 0; j < 9; j++) {
      int p = 8;
      ss >> p;
      cout << p;
    }
    cout << endl;
  }
  return 0;
}

Now, if i compile it an run it with ./a.out < test.txt where text.txt contains:

1 2 3 4 5 6 7 8 9
2 2 3 4 5 6 7 8 9
3 2 3 4 5 6 7 8 9
4 2 3 4 5 6 7 8 9
5 2 3 4 5 6 7 8 9
6 2 3 4 5 6 7 8 9
7 2 3 4 5 6 7 8 9
8 2 3 4 5 6 7 8 9
9 2 3 4 5 6 7 8 9

It will output (without spaces):

8 8 8 8 8 8 8 8 8
2 2 3 4 5 6 7 8 9
3 2 3 4 5 6 7 8 9
4 2 3 4 5 6 7 8 9
5 2 3 4 5 6 7 8 9
6 2 3 4 5 6 7 8 9
7 2 3 4 5 6 7 8 9
8 2 3 4 5 6 7 8 9
9 2 3 4 5 6 7 8 9

Why is the first line wrong? I've tried reading the first line out of the loop as well.
Also, if I replace ss > p with cin > p I just get an output table full of 8's.

This is not making any sense!!

Okay you guys were right. Some weird stuff as the first character of my input file:

od -c test.txt
0000000 357 273 277   2       0       5       0       0       7       0
0000020       0       6  \n   4       0       0       9       6       0
0000040       0       2       0  \n   0       0       0       0       8

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

杀お生予夺 2024-10-10 19:20:04

这是数据的问题(因为代码看起来没问题)。您很可能已经使用带有 BOM 的 UTF-8 编码保存了文本文件。 UTF-8 BOM 是文件开头的三个字节,尝试将它们解释为十进制数字规范将会失败。

第二、第三、第四行等。好的,因为您正在为每一行创建新的 istringstream 对象,因此不会保留上一行的错误模式。

因此,修复:保存不带 BOM 的文件 - 假设 BOM 假设是正确的。

干杯&呵呵,

It's a problem with the data (since the code looks OK). Most probably you've saved your text file with UTF-8 encoding with BOM. An UTF-8 BOM is three bytes at the start of the file, and trying to interpret those as a decimal number specification would fail.

Second, third, fourth line etc. OK because you're creating new istringstream object for each line, so not retaining error mode from previous line.

So, fix: save the file without BOM -- assuming the BOM hypothesis is correct.

Cheers & hth.,

时光是把杀猪刀 2024-10-10 19:20:04

你的代码对我来说似乎很好,如果我是你,我会仔细检查输入文件:你确定第一行没有空,或者第一行的开头没有一些非数字字符?

Your code seems fine to me, if I were you I'd double check the input file : are you sure there is no empty first line, or some non-numeric character on the beginning of line 1 ?

十雾 2024-10-10 19:20:04

我怀疑您编写了自己的 getline(),并且错误就在那里。 InputStreams 有一个 getline(char*, int) ,我怀疑您将 string.begin() 塞入第一个参数,并将一些其他数字塞入后者。

不要那样做。

您的程序应该做的就是将输入复制到输出(给定此代码和该输入)。即使在“有效”的路线上,它也没有这样做。

我在这里看到了一些经验不足的程序员的“签名”。
1) 变量名过短(在 for 循环计数器之外),“ss”和“p”
2) 神奇错误数 (8),尤其是从数据中不明显的错误数。
3)“使用”

1和3都暗示缺乏打字速度,因此缺乏经验......尽管你有1k+声誉(这主要基于提出问题......情况变得更加清晰)。

我会重写它,如下所示:

int curDig;
curLine >> curDig;
if (curLine.good()) {
  cout << curDig;
} else {
  cout << "FAILED at line: " << lineIdx << " containing: " << line << std::endl;
}

有可能,您会立即看到“FAILED at line: 0 contains:”,因为我认为您的 getline()< 中存在错误/代码>。

I suspect you wrote your own getline(), and the bug is there. InputStreams have a getline(char*, int), and I suspect your cramming string.begin() into the first param, and Some Other Number into the latter.

Don't do that.

All your program should be doing is copying the input to the output (given this code and that input). It's not doing that either, even on the lines that "work".

I am seeing a number of Not So Experienced Programmer 'signatures' here.
1) Overly short variable names (outside a for loop counter), "ss" and "p"
2) Magic error number (8), particularly one that doesn't stand out from the data.
3) "using"

1 and 3 both hint at a lack of typing speed, and therefore experience... despite your 1k+ reputation (which is based mostly on asking questions... the situation becomes clearer).

I'd rewrite it something like this:

int curDig;
curLine >> curDig;
if (curLine.good()) {
  cout << curDig;
} else {
  cout << "FAILED at line: " << lineIdx << " containing: " << line << std::endl;
}

Chances are, you're going to see "FAILED at line: 0 containing: " right out of the gate, due to what I think is a bug in your getline().

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文