在C++中删除多余的空格

Dam*_*ian 16 c++ string algorithm

我试着编写一个删除多余空格的脚本,但我没有设法完成它.

基本上我想转变abc sssd g g sdg gg gfabc sssd g g sdg gg gf.

在PHP或C#等语言中,它很容易,但在C++中却没有,我知道.这是我的代码:

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <cstring>
#include <unistd.h>
#include <string.h>

char* trim3(char* s) {
    int l = strlen(s);

    while(isspace(s[l - 1])) --l;
    while(* s && isspace(* s)) ++s, --l;

    return strndup(s, l);
}

char *str_replace(char * t1, char * t2, char * t6)
{
    char*t4;
    char*t5=(char *)malloc(10);
    memset(t5, 0, 10);
    while(strstr(t6,t1))
    {
        t4=strstr(t6,t1);
        strncpy(t5+strlen(t5),t6,t4-t6);
        strcat(t5,t2);
        t4+=strlen(t1);
        t6=t4;
    }

    return strcat(t5,t4);
}

void remove_extra_whitespaces(char* input,char* output)
{
    char* inputPtr = input; // init inputPtr always at the last moment.
    int spacecount = 0;
    while(*inputPtr != '\0')
    {
        char* substr;
        strncpy(substr, inputPtr+0, 1);

        if(substr == " ")
        {
            spacecount++;
        }
        else
        {
            spacecount = 0;
        }

        printf("[%p] -> %d\n",*substr,spacecount);

        // Assume the string last with \0
        // some code
        inputPtr++; // After "some code" (instead of what you wrote).
    }   
}

int main(int argc, char **argv)
{
    printf("testing 2 ..\n");

    char input[0x255] = "asfa sas    f f dgdgd  dg   ggg";
    char output[0x255] = "NO_OUTPUT_YET";
    remove_extra_whitespaces(input,output);

    return 1;
}
Run Code Online (Sandbox Code Playgroud)

它不起作用.我尝试了几种方法.我想要做的是逐个字符地迭代字符串并将其转储到另一个字符串中,只要一行中只有一个空格; 如果有两个空格,请不要将第二个字符写入新字符串.

我怎么解决这个问题?

Chr*_*phe 26

已经有很多很好的解决方案.我建议您基于专用的替代方案,<algorithm>以避免连续重复 unique_copy():

void remove_extra_whitespaces(const string &input, string &output)
{
    output.clear();  // unless you want to add at the end of existing sring...
    unique_copy (input.begin(), input.end(), back_insert_iterator<string>(output),
                                     [](char a,char b){ return isspace(a) && isspace(b);});  
    cout << output<<endl; 
}
Run Code Online (Sandbox Code Playgroud)

这是一个现场演示. 请注意,我从c样式字符串更改为更安全和更强大的C++字符串.

编辑:如果代码中需要保留c风格的字符串,则可以使用几乎相同的代码但使用指针而不是迭代器.这就是C++的神奇之处.这是另一个现场演示.

  • 顺便说一句:你可能想在你的答案中添加cstring-solution. (2认同)

vil*_*apx 8

这是一个简单的非C++ 11解决方案,使用与问题相同的remove_extra_whitespace()签名:

#include <cstdio>

void remove_extra_whitespaces(char* input, char* output)
{
    int inputIndex = 0;
    int outputIndex = 0;
    while(input[inputIndex] != '\0')
    {
        output[outputIndex] = input[inputIndex];

        if(input[inputIndex] == ' ')
        {
            while(input[inputIndex + 1] == ' ')
            {
                // skip over any extra spaces
                inputIndex++;
            }
        }

        outputIndex++;
        inputIndex++;
    }

    // null-terminate output
    output[outputIndex] = '\0';
}

int main(int argc, char **argv)
{
    char input[0x255] = "asfa sas    f f dgdgd  dg   ggg";
    char output[0x255] = "NO_OUTPUT_YET";
    remove_extra_whitespaces(input,output);

    printf("input: %s\noutput: %s\n", input, output);

    return 1;
}
Run Code Online (Sandbox Code Playgroud)

输出:

input: asfa sas    f f dgdgd  dg   ggg
output: asfa sas f f dgdgd dg ggg
Run Code Online (Sandbox Code Playgroud)


ana*_*lyg 6

由于您使用C++,因此您可以利用为此类工作设计的标准库功能.您可以使用std::string(而不是char[0x255])和std::istringstream,它将替换大多数指针算法.

首先,创建一个字符串流:

std::istringstream stream(input);
Run Code Online (Sandbox Code Playgroud)

然后,从中读取字符串.它将自动删除空白分隔符:

std::string word;
while (stream >> word)
{
    ...
}
Run Code Online (Sandbox Code Playgroud)

在循环内部,构建输出字符串:

    if (!output.empty()) // special case: no space before first word
        output += ' ';
    output += word;
Run Code Online (Sandbox Code Playgroud)

这种方法的一个缺点是它动态分配内存(包括几个重新分配,在输出字符串增长时执行).