【问题标题】:Removing Extra Whitespace in C++在 C++ 中删除多余的空格
【发布时间】:2018-02-17 00:54:00
【问题描述】:

我正在尝试编写从文件或标准输入中读取的代码,并导致文件或标准输入中的所有空白被“压缩”,这意味着只有最后一个空白字符序列打印空白。我的方法是创建一个映射,其中每个单词作为键,该单词后面的空格作为它的值。这可能有问题,因为我需要按插入顺序打印地图的内容,而且我也会有重复的键。我发现了 std::unordered_multimap 但我无法弄清楚我将如何实施它。

这是我所拥有的:

#include <iostream>
#include <fstream>
#include <stdio.h>
#include <string.h>
#include <vector>
#include <iterator>
#include <algorithm>
#include <sstream>
#include <map>

using namespace std;

int main(int argc, char** argv) {

    string filename;
    char input;
    map<string, string> words;
    ostringstream os;
    string word = "";
    string spaces = "";

    filename = argv[argc-1];
    ifstream infile(filename);

    while ( infile.get(input) ) {
        os << input;
    }

    string filecontents = os.str();

    for (int i = 0; i < filecontents.length(); ++i) {
        if ( !isspace(filecontents[i])) {
            if (spaces.length() >= 1) {
                words[word] = spaces;
                word = "";
                spaces = "";
                word += filecontents[i];
            }

            else {
                word += filecontents[i];
            }
        }

        else {
            spaces += filecontents[i];
        }
    }

    words[word] = "";

    for (const auto& p : words) {
        cout << p.first << p.second.back();
    }

文件:

potato   milk   

sausage

输出:

milk
potato sausage

也许有更好的方法来做这件事?我应该补充一点,我是 C++ 的新手,嗯,一般来说是 C。任何帮助将不胜感激。

【问题讨论】:

  • 如果命令行上没有指定参数——你是不是有点麻烦?
  • mapunordered_multimap 和任何关联容器都不会保留插入顺序。只是一个std::vector&lt;std::pair&lt;std::string, std::string&gt;&gt; 怎么样?
  • 也许您只需要自己存储这些单词,因为它们都有一个空格分隔它们? std::vector&lt;std::string&gt;
  • C 的新手或知识与 C++ 的关系不大。它们是不同的语言,尽管它们有一些共同的语法和特性,但用两种语言做某件事的最佳方式通常是完全不同的。
  • “我是 C++ 新手,嗯,一般来说是 C” 听起来你认为 C++ 是一种 C。它不是

标签: c++ string c++11 dictionary whitespace


【解决方案1】:

您可能有点过度思考逻辑。如果您希望能够从作为第一个参数给出的文件名中读取,或者如果没有给出参数,则从 stdin 中读取,您可以创建一个函数,从输入流中读取 string 并简单地输出由 a 分隔的所有单词通过将istream 引用传递给函数并传递打开的ifstreamstd::cin,空格(专门处理第一个单词)。

一个简短的例子可能如下所示:

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

void squishws (std::istream& in)
{
    bool first = true;
    std::string str;

    while (in >> str)   /* while words read */
        if (first) {    /* no space before 1st word */
            std::cout << str;
            first = false;
        }
        else            /* output remaining words with 1 space */
            std::cout << " " << str;

    std::cout << "\n";  /* tidy up with newline */

}

int main (int argc, char **argv) {

    if (argc > 1) {     /* read from file if given as argument */
        std::ifstream f (argv[1]);
        if (f.is_open()) 
            squishws (f);
        else {
            std::cerr << "error: file open failed.\n";
            return 1;
        }
    }
    else {  /* read from stdin */
        squishws (std::cin);
    }

    return 0;
}

您可以根据需要添加输出文件引用,或者只是将输出重定向到命令行上的输出文件。

输入文件示例

$ cat dat/wswords.txt
this       is         a

file    with


multiple

whitespace.

使用/输出示例

$ ./bin/file_rmwhitespace < dat/wswords.txt
this is a file with multiple whitespace.

【讨论】:

    【解决方案2】:

    由于std::string 的流提取运算符重载会吃掉空格,您可以使用它,然后将空格添加到输入:

    std::string word;
    while (data_file >> word)
    {
      std::cout << word << " ";
    }
    

    如果你想逐行输入,你可以用std::istringstream做类似的事情:

    std::string text_line;
    while (std::getline(data_file, text_line))
    {
      std::string word;
      std::istringstream text_stream(text_line);
      while (text_stream >> word)
      {
        std::cout << word << " ";
      }
      std::cout << "\n";
    }
    

    您可能想要添加一些添加逻辑来删除行尾的多余空格。

    【讨论】:

      猜你喜欢
      • 2016-05-19
      • 1970-01-01
      • 1970-01-01
      • 2023-01-16
      • 2019-03-03
      • 1970-01-01
      • 1970-01-01
      • 2012-01-24
      • 2013-07-20
      相关资源
      最近更新 更多