在C ++中删除额外的空格

时间:2018-02-17 00:54:00

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

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

这就是我所拥有的:

npm ERR! git clone git@github.com:angular/cli Cloning into bare repository '/home/jonah/.npm/_git-remotes/git-github-com-angular-cli-515723dd'...
npm ERR! git clone git@github.com:angular/cli Permission denied (publickey).
npm ERR! git clone git@github.com:angular/cli fatal: Could not read from remote repository.
npm ERR! git clone git@github.com:angular/cli 
npm ERR! git clone git@github.com:angular/cli Please make sure you have the correct access rights
npm ERR! git clone git@github.com:angular/cli and the repository exists.
npm ERR! addLocal Could not install angular/cli
npm ERR! Error: ENOENT: no such file or directory, stat 'angular/cli'
npm ERR! If you need help, you may report this *entire* log,
npm ERR! including the npm and node versions, at:
npm ERR!     <http://github.com/npm/npm/issues>

npm ERR! System Linux 4.11.0-parrot6-amd64
npm ERR! command "/usr/bin/node" "/usr/bin/npm" "install" "--unsafe-perm" "-g" "@angular/cli"
npm ERR! cwd /home/jonah/.npm-global/lib
npm ERR! node -v v8.9.3
npm ERR! npm -v 1.4.21
npm ERR! path angular/cli
npm ERR! syscall stat
npm ERR! code ENOENT
npm ERR! errno -2
npm ERR! 
npm ERR! Additional logging details can be found in:
npm ERR!     /home/jonah/.npm-global/lib/npm-debug.log
npm ERR! not ok code 0

文件:

#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

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

2 个答案:

答案 0 :(得分:2)

你可能会过度思考逻辑。如果您希望能够从作为第一个参数给出的文件名中读取,或者如果没有给出参数,则从stdin读取,您可以创建一个从输入流中读取string的函数,并简单地输出所有由空格分隔的单词(特别处理第一个单词),方法是将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.

答案 1 :(得分:1)

由于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";
}

您可能需要添加一些添加逻辑,以消除行尾的额外空间。