Передача массива символов в качестве аргументов функции - PullRequest
0 голосов
/ 03 октября 2018

Я пытаюсь передать строку в качестве аргумента функции, и она выдает ошибку ошибки сегментации (Core Dumped).Не могли бы вы сообщить мне, какую ошибку я здесь делаю?Вот код:

replaceChars(char str[], char sChar[], char rChar)
{
int i,j;
printf("rChar is %c", rChar);
printf("sChar is %s", sChar);

for(i = 0; i <= strlen(str); i++)
{
    for(j = 0; j <= strlen(sChar); j++)
    {
     if(str[i] == sChar[j])  
     {
        str[i] = rChar;
        //printf("The New String is %c", str[i]);
     }
    }
}

printf("The New String is %s", str);
}
void main()
{
char myString[36], schar[36], rchar;

printf("Please enter a string:");

scanf("%[^\n]s", &myString);

printf("Which characters to replace?");
scanf(" %[^\n]c", &schar);
printf("With which character?");
scanf(" %[^\n]c", &rchar);

replaceChars(myString, schar, rchar);

}

Ответы [ 2 ]

0 голосов
/ 04 октября 2018

Не могли бы вы сообщить мне, какую ошибку я здесь совершаю?

В дополнение к @ dbush хорошему ответу, код OP неоправданно неэффективен.

Используя приведенный ниже исправленный код, и предположим, что начальная длина str, sChar равна S,C соответственно.

for(i = 0; i < strlen(str); i++) {
  for(j = 0; j < strlen(sChar); j++) {
    if(str[i] == sChar[j]) {
      str[i] = rChar;
    }
  }
}

for(i = 0; i < strlen(str); i++) {, а с последующим str[i] = rChar; обязывает код:найдите длину от str до S раз, и каждый strlen(str) требует O (S) операций.

Если бы S было нетривиальным значением, скажем 1000, это 1000 * 1000 могло бы легко повлиять на общую производительность.Простым решением является вычисление длины один раз или поиск нулевого символа .

// for(i = 0; i < strlen(str); i++) {
S = strlen(str);
for(i = 0; i < S; i++) {
// or
for(i = 0; str[i]; i++) {

То же самое происходит и с внутренним циклом.Тем не менее, умный компилятор может видеть, что sChar не меняется, и может использовать преимущество понимания, что strlen() не имеет побочных эффектов, которые могли бы привести к другому результату.При такой оптимизации strlen(sChar) действительно можно вызвать один раз, даже если strlen(sChar) внутри более высокого цикла for (i...).

Тем не менее просто и идиоматично просто проверить нулевой символ .

    // for(j = 0; j < strlen(sChar); j++)
    // better as
    for(j = 0; sChar[j]; j++)

Но почему это не относится к циклу for(i = 0; i < strlen(str); i++)?

В этом цикле код может изменять str[], поэтому компилятор не может сделатьоптимизация как при for(j = 0; sChar[j]; j++).

. Здесь также возникает вопрос: что должен делать код, если заменяющий символ rChar является нулевым ?

На мой взгляд, код можно продолжить, заменив его '\0 несколько раз, или просто вернуть после этого.

       str[i] = rChar;
       if (rChar == '\0') return; // Possible way to handle \0
0 голосов
/ 03 октября 2018

Здесь две проблемы.

Во-первых, когда вы просматриваете str и sChar:

Я пытаюсь передать строку в качестве аргумента функции ион выдает ошибку Сегментации (Core Dumped).Не могли бы вы сообщить мне, какую ошибку я здесь делаю?Вот код:

for(i = 0; i <= strlen(str); i++)
{
    for(j = 0; j <= strlen(sChar); j++)
    {

Вы используете <= в качестве условия выхода.Индексы массива начинаются с 0, поэтому допустимые индексы - от 0 до длины-1.Вы переходите от 0 к длине, так что вы переходите в конец массива.Чтение после конца массива вызывает неопределенное поведение .

Изменение условий для использования <:

for(i = 0; i < strlen(str); i++)
{
    for(j = 0; j < strlen(sChar); j++)
    {

Вторая проблема заключается в том, как вычтение значений:

scanf("%[^\n]s", &myString);
...
scanf(" %[^\n]c", &schar);
...
scanf(" %[^\n]c", &rchar);

Спецификатор формата %[] не требует никаких символов после него, и ему требуется char * в качестве параметра, который указывает на первый элемент массива char.В первых двух случаях вы передаете адрес массива вместо самого массива (который распадается на указатель), и у вас появляется дополнительный символ после формата %[], который не нужен.В третьем случае вы передаете указатель на один char, когда в формате ожидается указатель на несколько символов.Поскольку вы хотите прочитать один символ, вы должны использовать вместо него спецификатор формата %c.

scanf("%35[^\n]", myString);
...
scanf(" %35[^\n]", schar);
...
scanf(" %c", &rchar);

Обратите также внимание, что первые два имеют ширину поля, которая ограничивает число читаемых символов, такчто вы не переполните массивы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...