用空白填充单词

时间:2013-09-04 14:09:45

标签: c char

我有以下代码,但有时我会得到奇怪的字符而不是空格:

char *getWord(const char *string)
{
    char *chars = "-_";
    int len = 0;
    int max = 10;
    char *res = malloc(max + 1);
    for ( ; len<max; string++) {
        if(*string)
        {
            if (!strchr(chars, *string)) {
                res[len] = *string;
                ++ len;
            }
        }
        else
        {
            res[len] = ' ';
            ++ len;
        }
    }
    res[len] = 0;
    return res;
}

ex:char * mystring =“my-str_a”; //结果我想成为:“mystra”接着是4个空白:“mystra”

如何填写单词结尾处的空白,直到达到最大长度?

5 个答案:

答案 0 :(得分:2)

char *getWord(const char *string)
{
    char *chars = "-_";
    size_t len ,max ;
    char *res ;

    max = 10;
    res = malloc(max + 1);
    if (!res) return 0;

    for (len = 0 ; *string && len < max; string++) {
        if (!strchr(chars, *string)) { res[len++] = *string; }
        }

    if (len < max) memset(res+len, ' ', max-len);
    res[max] = 0;
    return res;
}

使用strspn()/ strcspn()的第二个版本(如果字符大于一个或两个字符,这可能会更快)

char *getWord3(const char *string)
{
    char *chars = "-_";
    size_t dst,src,len ,max ;
    char *res ;

    max = 10;
    res = malloc(max + 1);
    if (!res) return 0;
    for (src=dst = 0 ; string[src] && dst < max; ) {
        len = strcspn( string+src, chars);
        if (len) {
                memcpy(res+dst,  string+src, len);
                src += len, dst += len;
                }
        len = strspn( string+src, chars);
        if (len) {
                src += len;
                }
        }

    if (dst < max) memset(res+dst, ' ', max-dst);
    res[max] = 0;
    return res;
}

答案 1 :(得分:1)

原始答案

一个问题是您缺少else的{​​{1}}子句,需要将该字符设置为空白。另一个问题是你读过字符串的结尾。

if (*string)

这使用传统的char *getWord(const char *string) { char *chars = "-_"; int max = 10; int len; char *res = malloc(max + 1); if (res == 0) return res; for (len = 0; len < max; len++) { if (*string) { if (!strchr(chars, *string)) res[len] = *string; else res[len] = ' '; string++; } else res[len] = ' '; } res[len] = 0; return res; } 循环来遍历已分配的数组。当代码未指向终端空字节时,代码仅递增for (int len = 0; len < max; len++)。每次迭代都有string的赋值。代码还检查内存分配是否成功 - 在实际程序中很重要。

修订答案

函数res[len]可以满足您的需求。请注意测试工具。

getWord2()

示例输出:

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

static
char *getWord1(const char *string)
{
    char *chars = "-_";
    int max = 10;
    int len;
    char *res = malloc(max + 1);
    if (res == 0)
        return res;
    for (len = 0; len < max; len++)
    {
        if (*string)
        {
            if (!strchr(chars, *string))
                res[len] = *string;
            else
                res[len] = ' ';
            string++;
        }
        else
            res[len] = ' ';
    }
    res[len] = 0;
    return res;
}

static
char *getWord2(const char *string)
{
    char *chars = "-_";
    int max = 10;
    int len = 0;
    char *res = malloc(max + 1);
    if (res == 0)
        return res;
    while (len < max)
    {
        if (*string)
        {
            if (!strchr(chars, *string))
                res[len++] = *string;
            string++;
        }
        else
            res[len++] = ' ';
    }
    res[len] = 0;
    return res;
}


int main(void)
{
    const char *data[] =
    {
        "my-str_a",
        "--m--__",
        "my str a",
        "AbyssinianElephant",
        "--m--__m--m--m-m-m-m-m-m-m-m-m-m",
    };

    for (size_t i = 0; i < sizeof(data)/sizeof(data[0]); i++)
    {
        char *res1 = getWord1(data[i]);
        char *res2 = getWord2(data[i]);
        char source[30];
        snprintf(source, sizeof(source), "<<%.25s>>", data[i]);
        assert(res1 != 0 && res2 != 0); // Reprehensible!

        printf("%-30.30s --> <<%s>> or <<%s>>\n", source, res1, res2);
        free(res1);
        free(res2);
    }
    return 0;
}

如果'mmmmmmmmmm'输出不是你想要的,那么规格需要收紧一点。调整可能并不难,但确实需要指定。

答案 2 :(得分:0)

更简单的方法:只需使用“read”和“write”指针沿着字符串爬行:

char *getWord(const char *string) {
    char *res = strdup(string);
    char *rp = res;
    char *wp = res;
    while(*rp) {
        if(*rp != '-' && *rp != '_') {
            *wp++ = *rp;
        }
        rp++;
    }
    while(wp < rp) {
        *wp++ = ' ';
    }
    return res;
}

答案 3 :(得分:0)

问题是,一旦传递变量string的终止空值,就不能依赖*string保持为空。结果是,当string长度小于max个字符时,您将获取终止空值后字节中的任何内容。

因此,一旦到达strlen(string),您需要填空,直至到达max。我不会推进'字符串'参数,而是用'len'代替它。

stringlen = strlen(string);
for (; len < max; len++ )
  if (len >= stringlen) {
    res[len] = ' ';
  } else if (*string[len]) {

等等。

答案 4 :(得分:0)

你必须检查标记字符串结尾的'\ 0'的第一个外观。在你的代码中,循环继续迭代并复制字符串结尾之后的所有乱码字符(即在'\ 0'之后)。垃圾字符来自于malloc保留内存但不清除它的事实(不会将内存中的值设置为零)。