在C中操作动态分配的2D char数组

问题描述 投票:1回答:3

我在尝试操作C中的2d动态数组时遇到问题。我想要做的是在2d数组的每一行中存储一个char字符串然后执行检查以查看该字符串是否包含某个字符,如果是删除所有出现的事件,然后转移空位置。实际发生的是我得到一个exit status 1

更多关于这个问题,例如,如果我有

Enter string 1: testing
Enter string 2: apple
Enter string 3: banana

我希望输出成为

What letter? a // ask what character to search for and remove all occurences
testing
pple
bnn

这是我的完整代码:

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


  void removeOccurences2(char** letters, int strs, int size, char letter){
    // Get size of array
    // Shift amount says how many of the letter that we have removed so far.
    int shiftAmt = 0;
    // Shift array says how much we should shift each element at the end
    int shiftArray[strs][size];

    // The first loop to remove letters and put things the shift amount in the array
    int i,j;
    for(i=0;i < strs; i++){
        for(j = 0; j < size - 1; j++) {

              if (letters[i][j] == '\0'){
                  break;
              }

              else {
              // If the letter matches

              if(letter == letters[i][j]){

              // Set to null terminator
              letters[i][j] = '\0';
              // Increase Shift amount
              shiftAmt++;
              // Set shift amount for this position to be 0
              shiftArray[i][j] = 0;
              }else{
              // Set the shift amount for this letter to be equal to the current shift amount
              shiftArray[i][j] = shiftAmt;
              }
              }
        }
      }  

    // Loop back through and shift each index the required amount
    for(i = 0; i < strs; i++){
        for(j = 0; j < size - 1; j++) {
          // If the shift amount for this index is 0 don't do anything


          if(shiftArray[i][j] == 0) continue;
          // Otherwise swap
          letters[i][j - shiftArray[i][j]] = letters[i][j];
          letters[i][j] = '\0';

        }

        //now print the new string
        printf("%s", letters[i]);
    }
    return;
  }

  int main() {
      int strs;
      char** array2;
      int size;
      int cnt;
      int c;
      char letter;
      printf("How many strings do you want to enter?\n");
      scanf("%d", &strs);
      printf("What is the max size of the strings?\n");
      scanf("%d", &size);
      array2 = malloc(sizeof(char*)*strs);
      cnt = 0;
      while (cnt < strs) {
          c = 0;
          printf("Enter string    %d:\n", cnt + 1);
          array2[cnt] = malloc(sizeof(char)*size);
          scanf("%s", array2[cnt]);
          cnt += 1;
      }

        printf("What letter?\n");
      scanf(" %c", &letter);
      removeOccurences2(array2,strs,size,letter);

  }

提前致谢!

c arrays memory-management
3个回答
3
投票

您可以从字符串中删除字母,因为您只能缩短字符串。

代码可能只是:

void removeOccurences2(char** letters, int strs, int size, char letter){
    int i,j,k;
    // loop over the array of strings
    for(i=0;i < strs; i++){
        // loop per string
        for(j = 0, k=0; j < size; j++) {
              // stop on the first null character
              if (letters[i][j] == '\0'){
                  letters[i][k] = 0;
                  break;
              }
              // If the letter does not match, keep the letter
              if(letter != letters[i][j]){
                  letters[i][k++] = letters[i][j];
              }
        }
        //now print the new string
        printf("%s\n", letters[i]);
    }
    return;
  }

但是你应该在返回环境之前释放所有已分配的数组,并在qazxsw poi结束时显式返回0。


3
投票

“......如果字符串包含某个字符,如果是,则删除所有出现的字符,然后转移到空位置。”

可以通过递增最初包含相同内容的两个指针来编辑原始字符串。以下说明:

main

这是我在执行此任务时看到的最干净,最简单的形式。 void remove_all_chars(char* str, char c) { char *pr = str://pointer read char *pw = str;//pointer write while(*pr) { *pw = *pr++; pw += (*pw != c);//increment pw only if current position == c } *pw = '\0';//terminate to mark last position of modified string }


2
投票

好吧,你的程序有几个问题,基本上你得到Credit goes to this answer错误,因为你正在访问未被你的程序分配的无效内存。以下是我发现的一些问题:

  1. 处理/检查导致segmentation fault值不正确的每个字符串后,shiftAmt不会重置。
  2. shiftArray的值仅根据预期的字符串长度设置,但之后(从每个字符串的长度到shiftArray的值)是随机数。
  3. 删除出现字符的逻辑是不正确的 - 您需要将出现字符后的整个字符串向左移动,而不是像操作您所做的那样操纵单个字符。

1和2导致分段错误错误(崩溃程序),因为它导致此行size访问意外的内存。您可以查看我编辑的letters[i][j - shiftArray[i][j]] = letters[i][j];方法版本以供参考:

removeOccurences2

这只是一个例子,它的逻辑中还有一些缺陷等着你完成。提示:尝试案例:“bananaaaa123”

快乐的编码!

© www.soinside.com 2019 - 2024. All rights reserved.