【问题标题】:C++ Why is my newline being misinterpreted?C++ 为什么我的换行被误解了?
【发布时间】:2014-12-03 21:04:34
【问题描述】:

我正在用 c++ 编写一个驱动程序,它最终需要将两个字符串传递给我在单独文件中编写的函数。我正在从格式如下的文件中读取数据:

ac: and
amo: love
amor: love
animal: animal
annus: year
ante: before, in front of, previously
antiquus: ancient
ardeo: burn, be on fire, desire
arma: arms, weapons
atque: and
aurum: gold
aureus: golden, of gold
aurora: dawn

我正在尝试将拉丁词放入一个字符串中,将英语等价词放入另一个字符串中。另外,每次我得到一个等效的英语时,我都希望能够将这两个字符串发送到我的函数。我的代码目前看起来像这样:

#include <iostream>
#include <fstream>
#include <string>

using namespace std;

//#include "tree.h"

int main(int argc, char* argv[])
{
    string latinWord   = "",
           englishWord = "";

    char   buffer;

    bool   isLatinWord = true;

    ifstream vocabFile;
    vocabFile.open(argv[1]);

    if (!vocabFile)
       cout << "File open failed." << endl;

    while(vocabFile.get(buffer))
    {

        if (isLatinWord)
        {
            if (buffer == ':')
                isLatinWord = false;

            else
                latinWord+= buffer;
        }

        else
        {
            if (buffer == ',') // indicates 1 of multiple equivs processed
            {
                cout << englishWord << " = " << latinWord << endl;
                englishWord = "";
            }

            else if (buffer == '\n') // indicates all english equivs processed
            {
                cout << englishWord << " = " << latinWord << endl;
                isLatinWord = true;
                englishWord = latinWord = ""; // reset both strings
            }

            else
                englishWord+= buffer;
        }
    }
}

这个应该起作用的方式是,如果有一个冒号,则表示拉丁单词字符串已完成填充(标志设置为 false),然后应该开始填充英文单词字符串。应该填充英文单词字符串,直到逗号被击中(此时将单词发送到函数)或换行符被击中(重置标志,因为此时已检查所有英​​文等效项)。

但是,当我尝试输出要发送到函数的字符串时,它们完全搞砸了。

这是我的输出:

$ ./prog5 latin.txt
 = ac
 = amo
 = amor
 = animal
 = annus
 before = ante
 in front of = ante
 = anteusly
 = antiquus
 burn = ardeo
 be on fire = ardeo
 = ardeo
 arms = arma
 = armas
 = atque
 = aurum
 golden = aureus
 = aureus
 = aurora

[编辑] 这是我在 isLatinWord 标志修复后的输出。 我认为我的代码以错误的方式识别换行符,我想知道是否有人看到任何错误或有任何建议?

谢谢, 本

【问题讨论】:

  • 一种可能更高级别的方法是读取文件中的每一行。然后根据“:”分隔符“拆分”每一行。我会首先创建一个函数来读取每一行,尽管 API 中可能已经有一个函数,然后我会编写另一个函数来分隔冒号处的行,尽管 API 中可能也已经有一个函数。
  • 你第一次读到buffer的单个字符。这是一个奇怪的设计,可能会解释一些问题。

标签: string file newline


【解决方案1】:

换行也可以表示为 \r\n 字符,我也会检查一下。

【讨论】:

  • 嗯,我认为问题在于代码中的换行条件在到达第一个英文单词之前就被认为是真的。我应该写一些代码来避免 \r\n 字符吗?
  • 理论上,C++ 库应该能够识别您编译的操作系统的“标准”换行符序列。所以,我认为,你不应该考虑它。但是 Windows 上的换行符是出了名的怪异!
  • 我会为 \r\n 写一个 if 语句,让我们看看这是否能解决你的问题,无论如何@AaronMcDaid,是的,你应该是对的,但是按照下面的建议使用 getline,而不是缓冲区读取。再一次,Windows 新行可能会很奇怪,所以即使在那时我也看到它不起作用! :-/
【解决方案2】:

这一行

latinWord = true;

应该是

isLatinWord = true;

【讨论】:

  • 谢谢!它似乎有正确的一些逻辑,但仍然不能解决我的换行问题。出于某种原因,一些英文单词显示得很好,但其他的只是空白!
【解决方案3】:

使用getline 读取(部分)行直到所需的分隔符:

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

int main() {
    string word;
    ifstream data("data.txt");

    string latin_word;
    while(getline(data,latin_word,':')) { // Read up to, but not including, the colon. But it does *discard* the colon
        cout << "Read latin word: <" << latin_word << '>' << endl;
        // Read the rest of the line
        string rest_of_line;
        getline(data, rest_of_line);
        // Now, we want to split it on commas. Easiest way is to build a stream object wrapped around this string
        istringstream rest_of_line_stream(rest_of_line);
        string english_phrase;
        while(
                  rest_of_line_stream >> std:: ws, 
                  getline(rest_of_line_stream, english_phrase,',')
             ) {
            cout << '@' << latin_word << "@\t@" << english_phrase << '@' << endl;
        }
    }
}

更新:我忘记丢弃足够的空格。 getline 默认保留任何前导空格。这可能是在此数据中的:, 之后出现的问题。因此,在尝试阅读英文短语之前,我使用rest_of_line_stream &gt;&gt; std:: ws 阅读并丢弃任何空格。

内部while 循环可能看起来有点奇怪。我在while 括号内有两件事:rest_of_line_stream &gt;&gt; std:: ws,然后是getline(rest_of_line_stream, english_phrase,',')。它们用逗号分隔,这是 C 和 C++ 中的 逗号运算符。基本上,它只是意味着评估了第一件事,但忽略了它的结果。用于 while 循环的布尔值就是 getline(rest_of_line_stream, english_phrase,',')

的结果

【讨论】:

    猜你喜欢
    • 2020-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-30
    • 1970-01-01
    • 2016-06-20
    • 1970-01-01
    相关资源
    最近更新 更多