从没有任何库的字符串中删除字符

时间:2014-12-18 16:45:08

标签: c

我需要从没有任何库的字符串中删除指定数量的字符。

此函数应该有三个参数:字符串,起始索引号和要删除的字符数。 我还没有学过指针,所以我无法使用它们。

我已经编写了这段代码,它适用于我的单个测试用例。我是否遗漏了任何错误,或改进或更好的方法来解决问题?

#include <stdio.h>

void removeString(char string[], int index, int number)
{
    int i, j;
    index--;

    for (i = index, j = index + number; string[j] != '\0'; i++, j++)
    {
        string[i] = string[j];
    }

    string[i] = '\0';
}

int main(void)
{
    char string[] = "this";

    removeString(string, 2, 2);

    printf("%s\n", string);
}

2 个答案:

答案 0 :(得分:4)

stdio是标准输入/输出的缩写。如果您没有输入或输出,则表示您未使用此库。

我能看到使用stdio执行此操作的唯一方法是控制输出的内容,即,如果不应该删除一个字符,则一次打印一个字符。这根本不会改变字符串。


相反,如果您只需要在没有的情况下使用任何其他库(不一定使用stdio)实现removeString方法,那么让我们先查看您现有的代码:

void removeString(char string[], int index, int number)
{
    int i, j;
    index--;

    for (i = index, ...)

如果index==0,会发生什么?看起来这应该是一个有效的输入,但你从i=-1开始。那么,只要我们不在索引中使用就可以可以

            string[i] = ...
亲爱的,我们刚刚在数组开始之前写过。我们需要更加小心。 j怎么样?

    for(..., j = index + number; string[j] != '\0'; i++, j++)
    {
        string[i] = string[j];

好吧,如果index+number大于我们字符串的长度,这是不好的 - 我们通过读取数组末尾来开始

安全版可能如下所示:

void removeString(char string[], int index, int number)
{
    int i, j;

    /* make sure inputs are sane */
    if (index < 0) index = 0;
    if (number < 1) number = 1;
    /* make sure index < strlen(string) without using strlen */
    for (i = 0; i<index; i++) {
        if (string[i] == '\0') return;
    }
    /* advance j, stopping if we hit the end */
    for (j = i+1; j < i+number && string[j]; j++) {}
    /* now copy from i to j, stopping at the end */
    do {
        string[i++] = string[j];
    } while (string[j++]);
}

具有以下不变量:

  • index不允许小于零
  • number不允许小于1(可以将此值设为零吗?)
  • 如果index大于字符串的总长度,则不会更改任何内容
  • 如果index+number大于字符串的总长度,我们会在index
  • 处截断字符串

考虑结构的有用方法是,我们的函数将字符串分为三个部分,每个部分都有一个循环:

  1. 在删除的部分(0 <= i <= index)之前是第一个循环
  2. 删除部分(index < j < index+number)内的
  3. 是第二个
  4. 删除部分(index <= i && index+number <= j <= end)之后
  5. 是第三个

  6. 由于您是初学者,因此值得注意的是,所有这三个循环都是经过精心编写的。也就是说,它需要注意使它们正确,并且使用更多常规形式可能更容易(也许更好的风格)。特别是,do/while循环有两个后增量表达式,它们必须位于正确的位置,这有点脆弱。

答案 1 :(得分:0)

试试此代码

#include <stdio.h>
void removeString(char string[], int index)
{
   int i = index - 1;
   for(; string[i] != '\0'; i++)
   {
    string[i] = string[i+1];
   }
}

int main(void)
{
   char string[] = "this";
   removeString(string, 2);
   printf("%s\n", string);
}
您的代码

错误

  • 您实际上只会获得ts代码,因为for loop方法中的所有removeString都是位置1处的单个赋值,其中值位于字符数组的第3位。

修改

你说你不知道指针,但你实际上是在程序中使用指针的概念。您如何认为void function能够对string进行更改,这是因为在您的removeString函数中,您实际上是在发送数组的基址以及对该内存所做的更改位置保持不变,您的printf语句引用了相同的位置,该位置在您之前的语句中经历了更改。那指针的魔力。