в чем проблема с этой функцией реверса символов?

#c #reverse #c-strings #function-definition

Вопрос:

поэтому я написал этот код, чтобы изменить одно из имен на основе опции пользователя.Идея состоит в том, чтобы использовать другую функцию для изменения и использования указателей, но после того, как я попробовал все, что я мог придумать, мой код вернул то же имя, но не изменил. лучшее, что я мог сделать, это изменить первую букву имени на странный знак.

 #include <iostream>

using namespace std;

void reverse(char* A) {
    int count = 0;
    char temp[10];
    for (int i = 0; A[i] != NULL; i  )
        count  ;
    for (int i = 0; A[i] != NULL; i  ) {
          temp[count]=A[i];
        count--;
    }
    for (int i = 0; A[i] != NULL; i  ) {
        A[i] = temp[i];
        
    }
    
}

int main(){
    int x= 0;
    int index;

    char Name_list[5][10];
    
    
    
    cout << "please enter the names of the student  " << endl;
    for (int i = 0; i < 5; i  ) {
        cin >> Name_list[i];

        for (int j = 0; Name_list[i][j] != NULL; j  ) {
            x  ;
        }
        while (x > 10)
        {
            x = 0;
            cout << "you have entered more then the allowed number of characters per name enter another name " << endl;
            cin >> Name_list[i];
            for (int j = 0; Name_list[i][j] != NULL; j  ) {
                x  ;
            }
        }
        x = 0;

    }
    for (int i = 0; i < 5; i  ) {
        cout << Name_list[i] << endl;
    }
    cout << "please enter the index of the name you want to reverse" << endl;
    cin >> index;
    while (index>4||index <0)
    {
        cout << "you entered incorrect index please enter a number from 0 to 4 " << endl;

    }
    reverse(Name_list[index]);
    for (int i = 0; i < 5; i  ) {
        cout << Name_list[i] << endl;
    }
    
    system("pause");

}
 

Комментарии:

1. Вы пытались отследить каждую строку reverse в отладчике?

2. Отладчик полезен, но вы также можете просто сделать это на бумаге. Начните со слова из 3 букв, нарисуйте несколько квадратов для слотов массива, следуйте своей логике и посмотрите, где заканчивается каждая буква.

3. Это не решает вопрос, но NULL является константой нулевого указателя. Это не char ценность. Это вполне может работать в этом коде, но правильное значение для терминатора строк-это ’’ .

4. @Усама, Предложение: вместо использования «список имен символов[5][10];», вы можете использовать «список имен строк[5]», а затем вы можете вызвать список имен[i].reverse (), чтобы изменить имя.

Ответ №1:

Для начала такая функция должна возвращать указатель на строку результата. То есть это должно быть объявлено так

 char * reverse( char *s );
 

Примечание: не используйте имена переменных, состоящие из прописных букв.

Тип int может быть недостаточно большим для хранения длины строки. Вместо этого используйте тип size_t .

 char * reverse( char *s )
{
    size_t count = 0;
    //...
 

Совершенно непонятно, почему существует массив с числом элементов, равным магическому числу 10

  char temp[10];
 

Чтобы изменить строку, нет необходимости объявлять вспомогательный массив. Такой подход принципиально неверен.

В этом цикле for

 for (int i = 0; A[i] != NULL; i  )
 

там сравнивается объект типа char с указателем NULL . Компилятор должен выдать сообщение о таком неправильном сравнении. Похоже, ты имеешь в виду

 for (int i = 0; A[i] != ''; i  )
 

В любом случае введенная переменная i в этом первом цикле for является избыточной, потому что у вас уже есть переменная count .

Поскольку у вас есть временная температура массива с фиксированным размером, равным 10, то оба цикла после первого цикла могут вызывать неопределенное поведение, даже если длина исходной строки в точности равна 10.

И результирующая строка не заканчивается нулем.

Функция может выглядеть следующим образом.

 char * reverse( char *s )
{
    size_t count = 0;

    while ( s[count] )   count;

    for ( size_t i = 0; i < count / 2; i   )
    {
        char c = s[i];
        s[i] = s[count - i - 1];
        s[count - i - 1] = c;
    }

    return s;
}
 

Или используя стандартные функции, вы можете написать функцию наоборот следующим образом

 #include <utility>
#include <cstring>

//...

char * reverse( char *s )
{
    for ( size_t i = 0, n = std::strlen( s ); i < n / 2; i   )
    {
        std::swap( s[i], s[n-i-1] ); 
    }

    return s;
}
 

Обратите внимание, что существует стандартный алгоритм std::reverse . Используя его, вы можете изменить строку следующим образом

 std::reverse( s, s   std::strlen( s ) );
 

Ответ №2:

 for (int i = 0; A[i] != NULL; i  ) {
    temp[count]=A[i];
    count--;
}
 

Если i увеличивается с 0 до 5, count снижается с 6 до 1.

Комментарии:

1. спасибо, все, что мне нужно было сделать, это -1 для нуля, я добавил 2 места для нуля, не заметив этого, я сразу же нашел способ решить эту проблему, изучив этот блок кода

Ответ №3:

Ладно, несколько вещей.

  1. Если вы хотите выполнить некоторые манипуляции со строками, загляните в stdlib. Если только вы не делаете это для занятий.
  2. Вы пишете все до конца временного буфера.
  3. Вам нужно добавить дополнительный символ в конце строк для нулевого байта (я думаю, что эта реализация может разрешить сегмент. ошибка)

Комментарии:

1. я знаю, но так как я учусь в классе, есть некоторые ограничения