为什么我的功能没有删除所有号码?

时间:2018-04-26 01:17:42

标签: c arrays char numbers

我创建了一个函数,可以在数组中找到任何数字并删除它们。这是我的代码:

int noNums (char *a) {
  int i;
  int deleteInd;
  for (i = 0; (i < MAX_NAME_SZ) && (a[i] != '\0'); i++) {
      if ((a[i] >= '0') && (a[i] <= '9')) {
      deleteInd = i;
      memmove (&a[deleteInd], &a[deleteInd + 1], strlen (a) - deleteInd);
      }
  }
}

如果一个数字本身就在char数组中,那么它就被删除了,没问题。但是,如果数组中有连续的数字,那么只会删除其他所有数字吗?

如果我的char数组有

  

w12345678

然后将数组更改为

  

w2468

而不是

  

瓦特

有什么想法吗?

3 个答案:

答案 0 :(得分:5)

执行memmove()后,下一个元素现在位于刚刚删除的元素的索引中。但是你的循环会i++,所以你不会再次检查那个索引。因此,只要一行中有两个数字,就跳过第二个数字。

解决此问题的一种方法是从数组的末尾循环到开头,而不是从开头到结尾。

另一种方法是在执行i--之后执行memmove(),以抵消循环将执行的i++

  if (isdigit(a[i]) {
      deleteInd = i;
      memmove (&a[deleteInd], &a[deleteInd + 1], strlen (a) - deleteInd);
      i--;
  }

顺便说一句,您应该使用isdigit()来测试一个字符是否为数字。

答案 1 :(得分:1)

您是否注意到您正在删除第一个数字然后跳过一个?

迭代数组时,从位置0开始递增。删除数字时,可以更改字符串索引。

i = 0 (char = w)
Index:  012345689
string: w12345678

i = 1 (char = 1)
Index:  012345689
string: w2345678

i = 2 (char = 3)
Index:  012345689
string: w2345678

基本上,只要删除角色,就会将字符串移动。

删除字符时不要增加i。

请注意,代码中不需要deleteInd,您可以直接使用i。

答案 2 :(得分:0)

这不是答案 - Barmar's是 - 但是这个和OP的other question表明他们可以使用新的方式来修改如何修改字符数组。

这是希望这对其他人学习C也很有用。

元素或元素序列可以通过对其内容的简单循环有效地从数组中删除。

关键是保留两个索引:一个用于下一个要检查的元素(或元素),一个用于存储的最后一个元素(或下一个要存储的位置)。

例如,要删除数组中的数字,可以使用以下伪代码函数:

Function removedigits(array, length):
    Let  i = 0      # Index of next element to examine, "input"
    Let  o = 0      # Position of next element to store, "output"

    While (i < length):
        If (array[i] is not a digit):
            Let  array[o] = array[i]
            Let  o = o + 1
        End If
        Let  i = i + 1
    End While

    # For a string, we'll also want to terminate the array
    # at o, because the rest of it contains garbage (old contents):
    Let  array[o] = '\0'
End Function

处理序列时,保留多个索引可能很有用。例如,要删除重复的行,可以使用以下函数:

Function removeduplicatelines(array):
    Let  i = 0         # Next position in the array to be examined
    Let  o = 0         # Next position in the array to store to
    Let  ostarted = 0  # Index at which the last line stored started at

    # Loop over each input line:
    While (array[i] != '\0'):

        # Find the length of this line. It can end with a newline
        # or at the end of the string. The newline is not included.
        Let  ilen = 0
        While (array[i + ilen] != '\n' && array[i + ilen] != '\0'):
            Let  ilen = ilen + 1
        End While

        # If the already stored line is of different length
        # (the +1 is for the newline, as it is not included in ilen)
        # or if it does not match the input line, store input line.
        If (ostarted + ilen + 1 != o || memcmp(array + ostarted, array + i, ilen) != 0):
            # The lengths or content differs. Store the line.

            # Copy ilen characters, starting at array[i],
            # to array[o] onwards.
            # Because the array parts do not overlap,
            # we can safely use memcpy() here.
            memcpy(array + o, array + i, ilen)

            # It is now the last stored line.
            Let  ostarted = o
            Let  o = o + ilen

            # If there is a newline following the line,
            # store that too.
            If (array[i + ilen] == '\n'):
                Let  array[o] = '\n'
                Let  o = o + 1
            End If

        Else:
            # It is the same line again. Do not store.
        End If

        # Proceed to the next input line.
        Let  i = i + ilen

        # Because the newline was not included in ilen,
        # skip it if there is one.
        If (array[i] == '\n'):
            Let  i = i + 1
        End If

    End While

    # After index o, the array may contain old contents;
    # so terminate the string at index o.
    Let  array[o] = '\0'
End Function

请注意,如果从memcmp()开始的ilen字符与从array + ostarted开始的字符匹配,array + i将返回零。

如果我们知道o永远不会超过i,则此方法有效;也就是说,我们永远不会覆盖尚未检查的数组内容。但请注意o允许等于i,因为这意味着我们会覆盖我们刚检查的相同字符,而不会对数组进行实际更改。

如果我们想要修改函数以便它跳过空行,我们在现有函数之前添加一个新的while循环,以删除任何前导换行符:

While (array[i] == '\n'):
    Let  i = i + 1
End While

并且,为了删除任何空行,我们将while循环中的最后一部分修改为

        # Because the newline was not included in ilen,
        # skip it (and any additional newlines) if there is one.
        While (array[i] == '\n'):
            Let  i = i + 1
        End While

最后,请注意上面的removeduplicatelines()在最后一行之后没有追加换行时要非常小心,如果阵列中没有一个换行符。