Строка удержания указателя - PullRequest
0 голосов
/ 23 октября 2018

Итак, я написал код, который вводит слово, берет его первую букву и помещает его в конец слова (например, «egg» будет «gge», а если мы повторим тот же процесс снова, это будет «geg ", а затем, наконец, обратно" яйцо ") Я хочу сделать этот процесс только 1 раз.И я хочу использовать указатель для запоминания начального значения слова, то есть яйца, а затем строка должна запомнить «gge».

Это код:

#include <iostream>
#include <cstring>
using namespace std;
int main()
{
    char s[100],aux,*P;
    int p=1,i,n,k,j;
    cin.get(s,100);
    i=0;
    while(i>=0)
    {
        P=s; //this is the pointer that SHOULD memorize "egg"
        aux=s[0]; 
        for(j=1; j<=n; j++) s[j-1]=s[j];
        s[n]=aux;//until here it does the letter thing
        break;
    }
     cout<<P<<endl<<s;//now here the pointer P should be "egg" and the string s should be "gge"
     //but the program prints out "gge" and "gge".

    return 0;
}

Что я делаю не так и как я должен делать то, что хочу?

Ответы [ 2 ]

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

Что я делаю не так и как я должен делать то, что хочу?

Вы, похоже, неправильно поняли, что такое указатель.Указатель - это переменная, которая указывает на что-то еще.В этом случае

char s[100];
char *P = s;

P указывает на первый символьный элемент s.Это тот же указатель, на который s затухает во многих контекстах.

У вас все еще есть только один массив для хранения 100 символов.У вас просто есть два идентификатора для этого массива, потому что вы можете получить его через s или P.

Если вы измените этот массив на месте с «egg» на «gge» или как угодно, P по-прежнему просто указывает на тот же массив, что и изначально.Он не сохранил ничего, кроме местоположения (адреса), и это не то, что изменилось.

Если я смогу пройти двумя дорогами, чтобы добраться до твоего синего дома, и ты перекрасишь дом в зеленый, одиндорог до сих пор не приводит к первоначальному синему дому.Это не то, как работают дороги, или как работают дома, или как работают указатели.

Вы хотите где-то хранить исходные 3 или 4 символа, что означает, что вам нужен еще один массив символов или, что лучше, std::string,Это сделает копию символов, которые вас интересуют, за до того, как вы их измените.

Минимальное рабочее изменение, вероятно,

// P = s <-- just stores the location
P = strdup(s); // <- copies the contents

, но учтите, что вам следует free(P) в какой-то момент после того, как вы закончите с этим.Переключиться на std::string действительно намного проще.


Простой пример использования семантики значения std::string для копирования:

#include <string>
#include <algorithm>
#include <iostream>

// source is a copy of the string passed
std::string rotate_left(std::string source, size_t offset = 1)
{
    std::rotate(source.begin(), source.begin()+offset, source.end());
    return source;
}

int main()
{
    std::string original{"eggsoup"};
    // for interactive use: getline(std::cin, original);

    std::string rotated = rotate_left(original);

    std::cout << original << '\n' << rotated << '\n';
}
0 голосов
/ 23 октября 2018

Это называется вращением строки.

Непонятно, почему вы решили использовать указатель для этого.Указатель не является строкой.Указатель не «содержит» свою собственную информацию *.Указатель указывает на некоторую часть информации.Здесь вы создаете указатель, который указывает на исходную строку, а затем вы изменяете эту строку ... но ваш указатель все еще просто указывает на эту же измененную строку.Указатель не знает, какую форму принимает строка, только , где она .

Если вы хотите сохранить копию исходной строки, вы должны буквально сделать это,либо путем копирования его элементов во второй массив char, либо путем переключения на std::string, потому что это 2018. 101

* Ну, очевидно, это так;он содержит адрес того, на что он указывает, который сам по себе является «информацией».Но это не та информация, которую вы хотели.

Если вы действительно хотите использовать указатель, вы можете получить ожидаемый результат, используя его, но не так, как выожидая (т.е. не сохраняя копию строки).Так как вы знаете, что повернули строку n раз, и вы знаете, где она начинается (это P!), И вы знаете, как долго она (это n, хотя вы в настоящее время не устанавливаетеэто, что является ошибкой), вы можете сделать некоторую математику, чтобы вывести исходную форму строки, просто перемещаясь по ее current форме в другом порядке.

const char* startOfString = &s[0];
const size_t lengthOfString = strlen(s);
const size_t numberOfRotations = 1;

// ... do your rotation here

// Now we can still print the original form, char by char, using MATHS!
for (size_t index = 0; index < lengthOfString; index++)
{
   const size_t adjustedIndex = (index + lengthOfString - numberOfRotations) % lengthOfString;
   std::cout << startOfString[adjustedIndex];
}

( live demo )

Но, с другой стороны, вы могли бы, в первую очередь, «выполнить» (или сделать вид, что выполняете) фактическое вращение таким же образом.

Или просто напечатайте строку, когда получите ее, прежде чем повернуть.

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