【问题标题】:how to use getline correctly如何正确使用getline
【发布时间】:2014-02-25 08:11:37
【问题描述】:

我写了一个使用getline()函数的程序,但是我不知道应该如何正确使用getline()。我在互联网上搜索过它,但我刚刚发现了一些关于将getchar()getline()cin.ignore() 一起使用的信息。我试过了,但都没有工作,我不知道问题出在哪里,为什么getline() 函数需要getchar()cin.ignore() 才能正常工作?

我的输入

2   
Alderaan   
1000.00 2000.00 3000.00   
Dantooine   
-1000.00 1000.00 1000.00   
Circarpous Major   
-500.00 500.00 -500.00   
Y’Toub   
-500.00 -500.00 500.00    

这是我的代码:

#include <cmath>
#include <string>
#include <cstdio>
#include <iostream>
using namespace std;
int main()
{
    long long int  x, y, z, x1, y1, z1;
    int n;
    cin >> n;
    string s, p;
    while (n--)
    {
        getline(cin, s);
        cin >> x;
        cin >> y;
        cin >> z; 
        cin.ignore();
        getline(cin, p);
        cin >> x1;
        cin >> y1;
        cin >> z1;
        cin.ignore();
        printf("%s to %s: %.2f\n", s.c_str(), p.c_str(), sqrt(pow(x - x1, 2) + pow(y - y1, 2) + pow(z - z1, 2)));
    }
}

【问题讨论】:

  • 当您说std::getline() 无法正常工作时,您究竟是什么意思?我很确定std::getline() 确实工作正常!但是请注意,您始终需要检查您的输入操作是否成功。此外,您的问题(我怀疑我知道您的问题是什么)实际上 回答了 无数次 次! (提示:您正在混合格式化和未格式化的输入)
  • 当然它工作正常,但我不知道如何使用它,这个函数是否需要像 getchar() 这样的其他函数才能工作???
  • 嗯,关于寻找解决方案要学习的一件事就是准确地表述问题所在!您说它不起作用,但没有说明效果是什么以及您的预期是什么。说明输入并不能真正描述什么不起作用。
  • @Dietmar Kühl 很抱歉我编辑了我的问题
  • 到目前为止,还没有描述。有一些无关紧要的提及您尝试解决问题的方法(“我在网上搜索...”),一些代码和一些输入。您没有说明 what 该程序的用途,也没有说明它是如何 失败的。是的,我确实知道它是如何以及为什么会失败(当读取上面的输入时,第二个字符串是空的并且值停止更改)但这不能让您解决下一个问题。

标签: c++ getline


【解决方案1】:

代码混合了格式化输入(即使用&gt;&gt; 运算符进行输入)和未格式化输入(在本例中使用std::getline())。未格式化的输入跳过前导空格,而格式化输入确实跳过前导空格。在这两种情况下,只要输入的下一个字符不符合格式,就会停止读取。

例如,当输入为3000.00\n... 时读取double 在读取最后一个0 后停止,因为'\n 不符合doubles 格式。因此,流中的下一个字符是\n。函数std::getline() 一直读取直到找到第一个\n,即立即:它提取那个字符并[成功] 产生一个空行。根据您的输入,序列Dantooine 是下一个,但不符合double 的格式并且流进入失败状态。

简单的解决方法是在从格式化输入切换到未格式化输入时始终跳过前导空格,例如,使用 std::ws 操纵器:

std::getline(std::cin >> std::ws, s);

这是否合适取决于您要阅读的内容。如果您要读取的字符串可以以空格开头,则需要更加小心,例如,仅将空格提取到下一个换行符:

std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');

(仅忽略一个字符可能不起作用,例如,如果行的输入以3000.00 \n 结尾)。

3000.00 读取为long 实际上停止在.,即,对程序的第一个更改是将读取的值类型更正为double 而不是long。请注意,您还应该始终在处理之前检查您的输入是否成功。也就是说,我实际上会使用这样的东西:

double      x0, y0, z0, x1, y1, z1;
std::string l0, l1;
while (0 < n--
       && std::getline(std::cin >> std::ws, l0)
       && std::cin >> x0 >> y0 >> z0
       && std::getline(std::cin >> std::ws, l1)
       && std::cin >> x1 >> y1 >> z1) {
    // do something with the input
}

【讨论】:

  • 你的答案很好,但是当我把它放在我的代码中时,我仍然无法得到我的真实结果,为什么????
  • @Danial:我没有看到您正在阅读 long 而不是 double。由于您没有描述问题(“它读取第一个 sx 正常,但其他一切都是错误的”)我没有发现:更改 xy 和 @ 的类型987654349@ 为double。由于缺少问题描述,所有答案(来自 Kerrek SB 的答案除外)都假定您正在查看与您目前实际遇到的问题不同的问题!
  • 输入文件将以包含整数 n (0
【解决方案2】:

试试看

#include <cmath>
#include <string>
#include <cstdio>
#include <iostream>
using namespace std;
int main()
{
    long long int  x, y, z, x1, y1, z1;
    int n;
    cin >> n;
    string s, p;
    while (n--)
    {
        cin.ignore();
        cin.clear();
        getline(cin, s);
        cin >> x;
        cin >> y;
        cin >> z;
        cin.ignore();
        cin.clear();
        getline(cin, p);
        cin >> x1;
        cin >> y1;
        cin >> z1;
        printf("%s to %s: %.2f\n", s.c_str(), p.c_str(), sqrt(pow(x - x1, 2) + pow(y - y1, 2) + pow(z - z1, 2)));
    }
}

你在第一次输入字符串时有两次。

【讨论】:

  • 请注意,此代码也不起作用,因为发布的输入实际上在最后一位数字和换行符之间包含多个空格!您需要跳过所有这些。
【解决方案3】:

最好不要混合使用令牌和行提取。如果要标记一行,只需使用字符串流。我会试试这个:

#include <string>
#include <sstream>
#include <iostream>

std::string n_str;   // for the first number, parse it later

if (!std::getline(std::cin, n_str))
{
    // error, die
}

for (std::string name, numbers;
     std::getline(std::cin, name) && std::getline(std::cin, numbers); )
{
    std::istringstream iss(numbers);
    double x, y, z;
    if (!(iss >> x >> y >> z >> std::ws) || iss.get() != EOF)
    {
        // parse error, die
    }

    // "name", "x", "y", "z" are usable now
}

【讨论】:

    【解决方案4】:

    cin &gt;&gt; z 不使用 \n 字符。因此,您需要一个cin.ignore() 来使用换行符并使下一个getline() 读取您想要的行。同样的问题也发生在cin &gt;&gt; z1

    【讨论】:

    • @dornhege:老师有点“邪恶”:如果您仔细查看输入,例如,通过编辑答案并将光标移动到行尾,您会看到换行符前有尾随空格!这实际上很好,因为老师强迫学生使用正确的方法来跳过空格!
    猜你喜欢
    • 1970-01-01
    • 2021-04-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多