Возникла ошибка сегментации при выполнении строковых манипуляций в C - PullRequest
0 голосов
/ 05 мая 2020

Я работаю над удалением обфускации подстроки из основной строки в C. Подстрока имеет формат xx:xx:xx:xx:xx:xx, где x может быть числом или буквой. В начале подстроки всегда есть пробел, но в конце подстроки не всегда есть пробел.

ex вход может быть "Found new device with wlan 33:33:33:33:33:33. Total 4 devices connected" выход должен быть "Found new device with wlan *. Total 4 devices connected"

Мне нужно сделать вспомогательную функцию для этого, и вот что я придумал:

//find the first occurency of ":" record as first_position_ptr and the last occurency of ":" record as last_position_ptr. 
// Add 2 to first_position_ptr to beginning of the substring and set it to "*"
// Subtract 2 from the last_position_ptr to get the pointer of the last charactor in substrung. 
// Iterate from 1 + first_position_ptr to last_position_ptr - 2 and set inStr to 0 to deleted the rest of substring. 

const char *proc(char *inStr) {
    const char tar[] = ":";
    char *first_position_ptr = strchr(inStr, tar[0]);
    char *last_position_ptr = strrchr(inStr, tar[0]);

    int first_position = (first_position_ptr == NULL ? -1 : first_position_ptr - inStr);
    int last_position = (last_position_ptr == NULL ? -1 : last_position_ptr - inStr);

    if (first_position != -1 && last_position != -1) {
        inStr[first_position + 2] = "*";
    }

    for (int i = (first_position + 1); i < (last_position + 2); i++) {
        inStr[i] = 0;
    }
    return inStr;
}

int main() {
    const char str[] = "Found new device with wlan 33:33:33:33:33:33. Total 4 devices connected";
    proc(*str);
    printf("%s\n", str);
    return 0;
}

Но когда я компилирую код, я сталкиваюсь с этими предупреждениями:

Jeff-MacBook-Pro-2:Desktop jBerman$ gcc test.c -o test
test.c:35:29: warning: incompatible pointer to integer conversion assigning to 'char' from
      'char [2]' [-Wint-conversion]
                inStr[first_position + 2] = "*";
                                          ^ ~~~
test.c:43:1: warning: control reaches end of non-void function [-Wreturn-type]
}
^
test.c:49:7: warning: incompatible integer to pointer conversion passing 'const char' to
      parameter of type 'char *' [-Wint-conversion]
        proc(*str);
             ^~~~
test.c:26:24: note: passing argument to parameter 'inStr' here
const char* proc(char *inStr){
                       ^
3 warnings generated.

Когда я запускаю его, компиляция говорит:

Segmentation fault: 11

Итак, я попытался исправьте эту строку в основном:

proc(*str) -> proc(&str);

Компилятор возвращает:

Bus error: 10

Кто-нибудь может сообщить мне, что может быть не так? Или, если вы поможете сделать это более эффективно, дайте мне знать

1 Ответ

1 голос
/ 05 мая 2020

Вы должны передать str в proc, а не *str и определить str как изменяемый массив char. Функцию proc также следует упростить: установка символов в середине на ноль не стирает среднюю часть, а останавливает строку после *. Чтобы сохранить конец строки, вы должны скопировать его с помощью memmove().

Вот измененная версия:

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

// replace the mac address from the input string with a *
char *proc(char *inStr) {
    char *p1 = strchr(inStr, ':');
    char *p2 = strrchr(inStr, ':');

    if (p1) {  // no need to test p2, there is at least one ':' in the string
        /* backtrack 2 characters, but not before the start of inStr */
        if (p1 > inStr) p1--;
        if (p1 > inStr) p1--;
        /* skip 3 characters, but not past the end of the string */
        p2++;
        if (*p2) p2++;
        if (*p2) p2++;
        /* replace the MAC address with a '*' */
        *p1++ = '*';
        /* move the rest of the string, including the null terminator */
        memmove(p1, p2, strlen(p2) + 1);
    }
    return inStr;
}

int main() {
    char str[] = "Found new device with wlan 33:33:33:33:33:33. Total 4 devices connected";
    printf("%s\n", proc(str));
    return 0;
}
...