如何用“X”替换前导或尾随空白字符

问题描述

寻找一种更有效的方法来替换前导和尾随空格 (' ') 并在每个空格的前面附加一个 'X' .. 对于尾随空格似乎可以正常工作,但我我想知道是否有更好/更简单的方法解决我所缺少的问题。

示例:

传入字符串:'12345 ' 预期结果'XXXXX12345'

删除了 5 个空格并在前面附加了 5 个 'X'

示例:

传入字符串:' 12345' 预期结果'XX12345'

删除 2 个空格并在前面附加 2 个 'X'

void fixStr(char* str)
{
    int i = 0;
    int length = strlen(str);
    char strcopy[10];
    strcpy(strcpy,str);

    for(i = 0; i < length; i++)
    {
        if(strcopy[i] == ' ')
        {
            strcopy[i] = '\0';
            str[i] = '\0';

            break;
        }
    }
    for(i = 0; i < length - i + 2; i++)
    {
        str[i] = 'X';
        str[i + 1] = '\0';
    }
    strcat(str,strcopy);

}

解决方法

以工程师的方式解决问题:

  1. 定义需求。
  2. 了解您的工具。
  3. 使用尽可能简单、尽可能准确的工具来制定解决方案。

就你而言:

  1. 需求:

    • 找出尾随空格的数量
    • 将字符串的内容移到末尾
    • 将开头设置为“X”
  2. 工具:

    • 测量、迭代、比较和计数
    • 移动一块内存
    • 初始化一块内存
  3. 解决方案示例:

    #include <string.h> /* for strlen(),memmove () and memset() */
    
    void fix_str(char * s)
    {
      if ((NULL != s) && ('\0' != *s)) /* Ignore NULL and empty string! */
      {
        /* Store length and initialise counter: */
        size_t l = strlen(s),i = l;
    
        /* Count space(s): */
        for (; (0 != i) && (' ' == s[i-1]); --i); /* This for loop does not need a "body". */
    
        /* Calculate the complement: */
        size_t c = l - i;
    
        /* Move content to the end overwriting any trailing space(s) counted before hand: */
        memmove(s+c,s,i); /* Note that using memmove() instead of memmcpy() is essential 
                               here as the source and destination memory overlap! */ 
    
        /* Initialise the new "free" characters at the beginning to 'X's:*/
        memset(s,'X',c);
      }
    }
    
,

实现这一点的一种方法是找出字符串的前导非空格位置和尾随非空格位置,然后将中间的内容(前导非空格,尾随非空格)移动到字符串的末尾,然后将开头的所有空格都设置为'x'

这样你就可以得到预期的输出(下面的函数)

void fixStr(char* str)
{
    int i = 0;
    int length = strlen(str);
    int leadindex = length; 
    int tailindex = 0;
    // First find the leading nonspace position
    for(i = 0; i < length; i++)
    {
        if(str[i] != ' ')
        {
            leadindex = i;
            break;
        }
    }
    
    // if not found nonspace then no change
    if( leadindex == length ) 
    {
        // all spaces,so no change required;
        return;
    }
    
    // Find the trailing nonspace position 
    for(i = length - 1; i >= 0 ; i--)
    {
        if(str[i] != ' ')
        {
            tailindex = i;
            break;
        }
    }
    
    // move the buffer (in place) to exclude trailing spaces
    memmove(str + (length - tailindex -1),str,(tailindex +1) );
    // set the 'x' to all empty spaces at leading ( you may use for loop to set this)
    memset(str,length - (tailindex - leadindex + 1) );

}
,

我没有修复您的代码,但您可以将 sprintfisspace 结合使用,类似于此。另外,请记住为字符串末尾的 '\0 留出一个空格。使用这个想法,它应该可以帮助你:

#include <ctype.h>
#include <stdio.h>

int main()
{
    char buf[11];
    char *s = "Hello";
    int i;
    
    sprintf(buf,"%10s",s); /* right justifies in a column of 10 in buf */
    
    for(i = 0; i < 10; i++) {
        if(isspace(buf[i])) /* replace the spaces with an x (or whatever) */
            buf[i] = 'x';
    }
    
    printf("%s\n",buf);
    
    return 0;
}