从C中的字符串中删除指定的char

时间:2015-06-02 14:53:27

标签: c string char

我正在创建一个将在一个字符串数组中搜索的程序,并且对于每个字符串,它将搜索指定的char。如果它找到了char,请将其删除。在这个例子中,我想删除字符' r'。

以下是代码:

void convertStrings(char **line) {
    for (int str = 0; str < MAX_LINE_LENGTH; ++str) {
        for (int ch = 0; ch < MAX_STR_LENGTH; ++ch) {
            if (line[str][ch] == 'r') {
                removeChar(line[str], 'r');
            }
        }
    }
}

void removeChar(char *str, char c) {
    int i = 0;
    int j = 0;

    while (str[i]) {
        if (str[i] != c) {
            str[j++] = str[i];
        }
        i++;
    }
    str[j]=0;
}

我不确定删除字符的算法是否正确,但主要错误是在其他地方。更具体地说,我在行中得到了一个分段错误:

if (line[str][ch] == 'r') {

为什么我会遇到段错误?另外,removeChar算法是否正确?

这是我的主要功能:

int main() {
    char line[3][10] = {"pep", "rol", "rak"};
    printf("%s\n", line[1]);
    convertStrings(line);
    printf("%s\n", line[1]);
    return 0;
}

提前致谢。

6 个答案:

答案 0 :(得分:2)

此代码适用于我的编译器:

#include<stdio.h>
#include<conio.h>
#define MAX_LINE_LENGTH 1024
#define MAX_STR_LENGTH 4
void removeChar(char *str, char c) {
int i = 0;
int j = 0;

while (str[i]) {
    if (str[i] != c) {
        str[j++] = str[i];
      }
    i++;
}
str[j]=0;
}

void convertStrings(char line[][MAX_STR_LENGTH]) {    //change 1
 for (int str = 0; str < MAX_LINE_LENGTH; ++str) {
    for (int ch = 0; ch < MAX_STR_LENGTH; ++ch) {
        if (line[str][ch] == 'r') {
removeChar(line[str], 'r');
        }
    }
  }
}


int main() {
 char line[3][MAX_STR_LENGTH] = {"pep", "rol", "rak"};   //change 2
 printf("%s\n", line[1]);
 convertStrings(line);
 printf("%s\n", line[1]);
 getch();
 return 0;
}

答案 1 :(得分:1)

这是因为line[str][ch]并不存在您为str和/或ch提供的所有价值。

您应该检查MAX_LINE_LENGTHMAX_STR_LENGTH的值,并确保它们是正确的。

答案 2 :(得分:1)

seg错误可能是因为您使用常量“MAX_LINE_LENGTH”和“MAX_STR_LENGTH”,但可能有行长度或字符串长度。我会在第一个for循环中使用数组的长度代替“MAX_LINE_LENGTH”,而使用数组的长度[str]而不是“MAX_STR_LENGTH”。除非您搜索的每个数组都有“MAX_LINE_LENGTH”并且每个字符串都有“MAX_LINE_LENGTH”,否则您将收到设置错误。希望这有帮助!

编辑:你可以通过除去数组的大小和元素类型的大小来找到数组的长度。

sizeof(array)/sizeof(array[0])

查找char指针的大小基本上是相同的过程。

答案 3 :(得分:1)

你有阵列

char line[3][10] = {"pep", "rol", "rak"};

将它传递给函数时,它会转换为char(*)[10]类型的指针。所以改变

void convertStrings(char **line) {

void convertStrings(char (*line)[10]) {

void convertStrings(char line[][10]) {

数组数组(2D数组)无法转换为指向指针的指针(在本例中为char**

另一个问题是you mention that MAX_LINE_LENGTH是1024而MAX_STR_LENGTH是4.这是错误的,因为循环将迭代并且您访问无效的内存位置。您应该将MAX_LINE_LENGTH设为3,将MAX_STR_LENGTH设为4,因为有3个字符串,每个字符串有4个字符。
您还可以将这些变量作为参数传递给函数convertStrings。更改在convertStrings

的声明中添加另外两个参数
void convertStrings(char (*line)[10], int MAX_LINE_LENGTH, int MAX_STR_LENGTH) {

void convertStrings(char line[][10], int MAX_LINE_LENGTH, int MAX_STR_LENGTH) {

并使用

main调用该函数
convertStrings(line, sizeof(line)/sizeof(*line), sizeof(*line)/sizeof(**line)); // `/sizeof(**line)` is 1 and is not needed

<小时/> 更好的方法是使用

void convertStrings(int MAX_LINE_LENGTH, int MAX_STR_LENGTH, char line[][MAX_STR_LENGTH]) {

void convertStrings(int MAX_LINE_LENGTH, int MAX_STR_LENGTH, char (*line)[MAX_STR_LENGTH]) {

并使用

调用该函数
convertStrings(sizeof(line)/sizeof(*line), sizeof(*line)/sizeof(**line), line); // `/sizeof(**line)` is 1 and is not needed

这样您就可以避免在函数中使用幻数10.

<小时/> 你肯定会从你的编译器得到一些警告。注意它们。如果您没有收到警告,请在编译器中启动警告并添加警告标志(如GCC中的-Wall)。

BTW,你可以从strchr查看string.h函数来查找字符串中是否存在字符。

答案 4 :(得分:1)

你得到一个段错误,因为数组line包含的字符串指针少于MAX_LINE_LENGTH,或者因为至少有一个指向字符串包含的字符数少于MAX_STR_LENGTH;更有可能是后者。

除了假定固定长度的固定数量的字符串之外,最好将实际数量的字符串作为参数传递。或者,您可以在列表末尾添加NULL作为哨兵值。

此外,没有理由假设每个字符串是固定长度。寻找终止字符('\0')以识别您何时到达终点。例如:

void convertStrings(char **line) {
    for (char **l = line; *l != NULL; l += 1) {
        for (int ch = 0; (*l)[ch]; ch += 1) {
            if ((*l)[ch] == 'r') {
                removeChar(*l, 'r');
            }
        }
    }
}

您的removeChar()功能看起来不错。

请注意,有些库函数可以帮助解决这个问题(例如strchr()),并且可以进行各种效率改进(例如只传递给removeChar()字符串尾部,从第一次出现的角色开始删除)。

答案 5 :(得分:1)

为什么要检查两次是否遇到'r'字符? (在两个功能中) 检查一次就足够了。

检测char的函数和删除它的函数?

我会这样做的:

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

void    convertStrings(char *line);
void    removeChar(char *str);

int     main(int argc, char *argv[]) {
    if (argc == 2)
    {
        printf("%s\n", argv[1]);
        convertStrings(argv[1]);
        printf("%s\n", argv[1]);
    }
    return (0);
}

void    convertStrings(char *line)
{
    for (int i = 0; line[i] != '\0'; i++)
    {
        if (line[i] == 'r') removeChar(&(line[i]));
    }
}

void    removeChar(char *str)
{
    int     i;

    i = 0;
    while (str[i] != '\0')
    {
        str[i] = str[i + 1];
        i++;
    }
}

但这是另一个只有一个功能的解决方案:

void convertStringsbis(char *line)
{
    int     delta;
    int     i;


    i = 0;
    delta = 0;
    while (line[i++ + delta] != '\0')
    {
        if (line[i + delta] == 'r')
            delta++;
        line[i] = line[i + delta];
    }
}