Преобразовать функцию XOR, чтобы она возвращала char*, а не строку

Я закодировал это XOR, используя строку, но теперь мне нужно вернуть char*. Я пытался сделать это часами, хотя я не привык работать с char. Думаю, я что-то здесь упускаю.

string XOR(string s, int key){

 string res = "";

 for (size_t temp = 0; temp < s.size(); ++temp){
  res += s[temp] ^ ((key + temp) % 255);
 }
 return res;

}

Как я могу изменить это, чтобы получить char* взамен?

Отредактировано, чтобы уточнить: мне нужен char*: char* XOR (строка s, ключ int)


person user2177904    schedule 16.03.2013    source источник
comment
Почему вы имеете в виду получить char взамен? Строка в стиле C?   -  person Shmil The Cat    schedule 17.03.2013
comment
Пожалуйста, покажите предлагаемую подпись метода, который вы хотите создать.   -  person Duncan Jones    schedule 17.03.2013
comment
Из возвращенного string вы можете вызвать c_str(), чтобы получить const char*.   -  person Peter Wood    schedule 17.03.2013
comment
Вам действительно нужно уточнить, что вы подразумеваете под возвратом символа. Как уже говорилось, вы спрашиваете, как вернуть значение одного символа. Я сомневаюсь, что это то, что вы имеете в виду, и если это так, вам нужно будет сообщить нам, как вы хотите, чтобы это значение char определялось.   -  person Keith Thompson    schedule 17.03.2013
comment
@PeterWood Я не думаю, что вы можете сделать это в этой функции, поскольку res просто выскочит из стека.   -  person antonijn    schedule 17.03.2013
comment
@PeterWood: если строка находится в стеке (как здесь), const char *, которое вы возвращаете из c_str(), будет недействительным в момент возврата функции.   -  person Jonathan Grynspan    schedule 17.03.2013
comment
@JonathanGrynspan Извините, я имел в виду, что функцию вообще не следует менять. Если пользователю 2177904 нужна строка символов, он уже может получить ее из возвращаемой строки. Они не должны изменять функцию, чтобы вместо этого просто возвращать c_str(), так как после окончания области действия функции возникают проблемы с продолжительностью жизни.   -  person Peter Wood    schedule 17.03.2013


Ответы (2)


РЕДАКТИРОВАТЬ: это было ошибкой, но исправлено с помощью @JonathanGrynspan и @john, и теперь моя окончательная версия:

Я знаю, что это не красиво, но делает то, что вы хотите:

char* XOR(string s, int key){
 string res = "";
 for (size_t temp = 0; temp < s.size(); ++temp){
  res += s[temp] ^ ((key + temp) % 255);
 }
 char * cstr = new char [res.length()+1];
 copy(res.begin(),res.end(),cstr);
 return cstr;
}
person 4pie0    schedule 16.03.2013
comment
Любая попытка использовать результат этой функции приведет к сбою, потому что владелец памяти по возвращаемому адресу уничтожается до того, как функция завершает возврат. - person Jonathan Grynspan; 17.03.2013
comment
извините @Jonathan Grynspan, это неправда, я пробовал, и это работает. ты пробовал? - person 4pie0; 17.03.2013
comment
@JonathanGrynspan, пожалуйста, обратитесь к этому - person 4pie0; 17.03.2013
comment
Я неправильно прочитал ваш пост и пропустил оператор new. Это по-прежнему неправильно, потому что вы утечете std::string, созданное с помощью new. - person Jonathan Grynspan; 17.03.2013
comment
Вы возвращаете указатель на s_ptr->c_str(), который не совпадает с s_ptr. Затем у вызывающего абонента есть строка C, которую он не может безопасно освободить, и просочившаяся std::string, которую он не может найти. - person Jonathan Grynspan; 17.03.2013
comment
если это не то же самое, почему вызывающий абонент не может безопасно освободить его? - person 4pie0; 17.03.2013
comment
@JonathanGrynspan, пожалуйста, посмотрите мой РЕДАКТИРОВАТЬ, теперь все в порядке? - person 4pie0; 17.03.2013
comment
Нет, теперь мы вернулись к исходной проблеме возврата указателя, который становится недействительным после завершения функции. - person Jonathan Grynspan; 17.03.2013
comment
И вызывающая сторона не может безопасно освободить строку C, потому что она принадлежит строке C++, и вы не знаете, как она была выделена, поэтому вы не знаете, как ее освободить. - person Jonathan Grynspan; 17.03.2013
comment
теперь std::string не уничтожается при возврате функции? и функция возвращает только копию строки (как const char*, преобразованную в char*)? обратите внимание, что это работает: ошибок нет, и если нет утечек, должно быть, тогда все в порядке - person 4pie0; 17.03.2013
comment
Функция возвращает копию строки C++, только если вы возвращаете строку C++. - person Jonathan Grynspan; 17.03.2013
comment
Это прослушивается. s_ptr уничтожается при выходе из функции, что освобождает память, на которую вы возвращаете указатель. То, что «это работает», не означает, что это правильно. - person john; 17.03.2013
comment
@john omg, пожалуйста, сначала запустите функцию, затем проголосуйте и прокомментируйте, я знаю, что это не нормально, но, конечно, это неправда, что вы сказали - person 4pie0; 17.03.2013
comment
@ cf16: функция не работает, как написано. Ваши доводы об обратном не делают его правильным. - person Jonathan Grynspan; 17.03.2013
comment
@JonathanGrynspan, не могли бы вы объяснить мне, где сейчас утечка памяти? - person 4pie0; 17.03.2013
comment
@ ct16 Теперь утечки нет. Теперь у вас есть память, используемая после освобождения. Это не утечка, это повреждение кучи. - person john; 17.03.2013
comment
@john Я запускаю эту функцию сейчас, в этот момент и не получаю ошибок - person 4pie0; 17.03.2013
comment
@cf16. Как я уже сказал, то, что он работает, не означает, что он не глючит. Беспокоит то, что вы работаете в сфере финансов программистом на C++ и, похоже, не понимаете основ. - person john; 17.03.2013
comment
Я запускаю этот код: string resp4=XOR(es,4); cout‹‹resp4; строка resp3=XOR(es,3); cout‹‹resp3; - person 4pie0; 17.03.2013
comment
@ cf16 Сейчас утечки нет, есть неопределенное поведение. Возвращаемый указатель указывает на недопустимую память. То, что он не падает, не свидетельствует о правильной работе, и в другой системе, с другим вводом или в другое время суток он может и будет падать. - person Jonathan Grynspan; 17.03.2013
comment
@JonathanGrynspan, может быть, сейчас все в порядке? - person 4pie0; 17.03.2013
comment
На самом деле все равно неправильно. strcpy() небезопасно и не должно использоваться (ваш компилятор, вероятно, предупредит вас об этом). В этом тривиальном случае это нормально, но вам, вероятно, следует заменить его на std::copy(res.begin(), res.end(), cstr);. - person Jonathan Grynspan; 17.03.2013
comment
да, я знаю, что это устарело, но в этом примере, когда я знаю, что копирую, все в порядке, но я изменил это, как вы предложили - person 4pie0; 17.03.2013
comment
@john и извиняюсь, так как вы были правы, я просто подумал кое о чем другом - person 4pie0; 17.03.2013

Является ли ваша входная строка перезаписываемой? Если это так, это самый простой и, вероятно, самый быстрый способ:

void XOR( char *input, int key ){
    for(int temp = 0; input[temp] != '\0'; ++temp){
        input[temp] ^= (key + temp) % 255;
    }
}

Он изменяет заданную строку вместо того, чтобы возвращать что-то новое. Но поскольку есть все шансы, что вы получите \0 символов в выводе, вы можете найти это более надежным:

void XOR( char *input, int key, int length ){
    for(int temp = 0; temp < length; ++temp){
        input[temp] ^= (key + temp) % 255;
    }
}

(очевидно, длина не изменилась)

Обновлять:

Увидев комментарии, возможно, это то, что вы хотите. Но будьте с ним осторожны; вам нужно будет помнить об освобождении возвращаемой памяти, к чему не привыкли программисты, использующие только C++;

char *XOR( const string &s, int key ) {
    const std::size_t l = s.size( );
    char *r = (char *) malloc( (l + 1) * sizeof( char ) );
    for( std::size_t i = 0; i < l; ++ i ) {
        r[i] = s[i] ^ ((key + (int) i) % 255)
    }
    r[l] = '\0'; // only needed if you need a null-capped string, which seems unlikely since your string could well contain nulls anyway
    return r;
}
person Dave    schedule 16.03.2013
comment
Спасибо, но я не хочу указывать длину. На самом деле мне нужен char*, а не char, поэтому сигнатура функции, которую я пытаюсь сделать, это char* XORED(string s, int key); Я пытался получить const char* с помощью c_str(), и мне это не удалось. Но я думаю, что есть лучший способ сделать это - person user2177904; 17.03.2013
comment
@ user2177904 см. обновленный ответ. Я думаю, что окончательный код - это то, что вы хотите. - person Dave; 17.03.2013