我在尝试在C中操纵2D动态数组时遇到麻烦。我要做的是将一个char字符串存储在2d数组的每一行中,然后执行检查以查看字符串是否包含某个字符,如果是这样,请删除所有出现的内容,然后移至空位置。实际发生的是我得到一个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);
}
谢谢!
答案 0 :(得分:3)
“ ...如果字符串包含某个字符,则删除所有出现的字符,然后移至空位置。”
可以通过增加两个最初包含相同内容的指针来在原位置编辑原始字符串。如下所示:
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
}
这是我执行此任务时看到的最干净,最简单的形式。 Credit goes to this answer 。
答案 1 :(得分: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;
}
但是您应该在返回环境之前释放所有分配的数组,并在main
的末尾显式返回0。
答案 2 :(得分:2)
好吧,您的程序上有几个问题,基本上是因为您正在访问程序未分配的无效内存而出现segmentation fault
错误。这是我发现的一些问题:
shiftAmt
值不正确的每个字符串后,不会重置shiftArray
。shiftArray
的值仅按预期的字符串长度设置,但此后(从每个字符串的长度到size
的值)为随机数。 1和2导致分段错误错误(导致程序崩溃),因为它导致此行letters[i][j - shiftArray[i][j]] = letters[i][j];
访问意外内存。您可以查看我的removeOccurences2
方法的编辑版本以供参考:
int removeOccurences2(char* string, char letter) {
if(!string) return -1;
int i = 0;
while (*(string+i) != '\0') {
if (*(string+i) == letter) {
memmove(string + i, string + i + 1, strlen(string + i + 1));
string[strlen(string) - 1] = '\0'; // delete last character
}
i++;
}
return 0;
}
这只是一个示例,其逻辑上仍有一些缺陷等待您完成。提示:尝试案例:“ bananaaaa123”
编码愉快!