标准算法是使用指针到开始/结束,并向内移动直到它们相遇或交叉在中间。随走随换,c++,c,string,reverse,C++,C,String,Reverse" /> 标准算法是使用指针到开始/结束,并向内移动直到它们相遇或交叉在中间。随走随换,c++,c,string,reverse,C++,C,String,Reverse" />

如何在C或C+中反转字符串+;? 如何在C或C++中反转字符串而不需要单独的缓冲区来保存反向字符串? #include <cstdio> #include <cstdlib> #include <string> void strrev(char *str) { if( str == NULL ) return; char *end_ptr = &str[strlen(str) - 1]; char temp; while( end_ptr > str ) { temp = *str; *str++ = *end_ptr; *end_ptr-- = temp; } } int main(int argc, char *argv[]) { char buffer[32]; strcpy(buffer, "testing"); strrev(buffer); printf("%s\n", buffer); strcpy(buffer, "a"); strrev(buffer); printf("%s\n", buffer); strcpy(buffer, "abc"); strrev(buffer); printf("%s\n", buffer); strcpy(buffer, ""); strrev(buffer); printf("%s\n", buffer); strrev(NULL); return 0; } 反向(str.begin(),str.end()); 这是C++中最简单的方法。 < P>标准算法是使用指针到开始/结束,并向内移动直到它们相遇或交叉在中间。随走随换

如何在C或C+中反转字符串+;? 如何在C或C++中反转字符串而不需要单独的缓冲区来保存反向字符串? #include <cstdio> #include <cstdlib> #include <string> void strrev(char *str) { if( str == NULL ) return; char *end_ptr = &str[strlen(str) - 1]; char temp; while( end_ptr > str ) { temp = *str; *str++ = *end_ptr; *end_ptr-- = temp; } } int main(int argc, char *argv[]) { char buffer[32]; strcpy(buffer, "testing"); strrev(buffer); printf("%s\n", buffer); strcpy(buffer, "a"); strrev(buffer); printf("%s\n", buffer); strcpy(buffer, "abc"); strrev(buffer); printf("%s\n", buffer); strcpy(buffer, ""); strrev(buffer); printf("%s\n", buffer); strrev(NULL); return 0; } 反向(str.begin(),str.end()); 这是C++中最简单的方法。 < P>标准算法是使用指针到开始/结束,并向内移动直到它们相遇或交叉在中间。随走随换,c++,c,string,reverse,C++,C,String,Reverse,反向ASCII字符串,即以0结尾的数组,其中每个字符都适合1char。(或其他非多字节字符集) 为什么,是的,如果输入被屏蔽了,这将愉快地在外部交换 在UNICODE中破坏时的有用链接: 另外,0x10000以上的UTF-8还没有经过测试(因为我似乎没有任何字体,也没有耐心使用hexeditor) 示例: $ ./strrev Räksmörgås ░▒▓○◔◑◕● ░▒▓○◔◑◕● ●◕◑◔○▓▒░ Räksmörgås sågrömskäR ./strrev verrts/. 非

反向ASCII字符串,即以0结尾的数组,其中每个字符都适合1
char
。(或其他非多字节字符集)

  • 为什么,是的,如果输入被屏蔽了,这将愉快地在外部交换
  • 在UNICODE中破坏时的有用链接:
  • 另外,0x10000以上的UTF-8还没有经过测试(因为我似乎没有任何字体,也没有耐心使用hexeditor)
示例:

$ ./strrev Räksmörgås ░▒▓○◔◑◕●

░▒▓○◔◑◕● ●◕◑◔○▓▒░

Räksmörgås sågrömskäR

./strrev verrts/.

非邪恶C,假设字符串是以null结尾的
char
数组的常见情况:

#include <stddef.h>
#include <string.h>

/* PRE: str must be either NULL or a pointer to a 
 * (possibly empty) null-terminated string. */
void strrev(char *str) {
  char temp, *end_ptr;

  /* If str is NULL or empty, do nothing */
  if( str == NULL || !(*str) )
    return;

  end_ptr = str + strlen(str) - 1;

  /* Swap the chars */
  while( end_ptr > str ) {
    temp = *str;
    *str = *end_ptr;
    *end_ptr = temp;
    str++;
    end_ptr--;
  }
}
#包括
#包括
/*PRE:str必须为NULL或指向
*(可能为空)以null结尾的字符串*/
无效STREV(字符*str){
字符温度*end_ptr;
/*如果str为NULL或空,则不执行任何操作*/
如果(str==NULL | |!(*str))
返回;
end_ptr=str+strlen(str)-1;
/*调换角色*/
while(end_ptr>str){
温度=*str;
*str=*end_ptr;
*end_ptr=温度;
str++;
结束_ptr--;
}
}

为了完整性起见,应该指出的是,在不同的平台上,字符串的表示形式中,每个字符的字节数根据字符的不同而不同。老派程序员会把这称为“错误”。现代程序员在(以及和其他)中更经常遇到这种情况。还有其他类似的编码

在这些可变宽度编码方案中,此处发布的简单算法(、或)根本无法正常工作!事实上,它们甚至可能导致字符串变得难以辨认,甚至在该编码方案中成为非法字符串。有关一些好的示例,请参见


STD::RetrySe()可能在这种情况下仍然有效,只要平台实现标准C++库(特别是字符串迭代器)正确地考虑了这一点。

请注意,std::reverse的优点在于它与
char*
字符串和
std::wstring
s以及
std::string
s一起工作

void strrev(char *str)
{
    if (str == NULL)
        return;
    std::reverse(str, str + strlen(str));
}

如果您正在寻找反向空终止缓冲区,这里发布的大多数解决方案都可以。但是,正如蒂姆·法利(Tim Farley)已经指出的那样,只有在假设字符串在语义上是字节数组(即单字节字符串)是有效的情况下,这些算法才会起作用,我认为这是一个错误的假设

例如,字符串“año”(西班牙语中的年份)

Unicode代码点为0x61、0xf1、0x6f

考虑一些最常用的编码:

拉丁语1/iso-8859-1(单字节编码,1个字符代表1个字节,反之亦然):

原件:

0x61、0xf1、0x6f、0x00

反向:

0x6f、0xf1、0x61、0x00

结果正常

UTF-8:

原件:

0x61、0xc3、0xb1、0x6f、0x00

反向:

0x6f、0xb1、0xc3、0x61、0x00

结果是胡言乱语和非法UTF-8序列

UTF-16大端码:

原件:

0x00、0x61、0x00、0xf1、0x00、0x6f、0x00、0x00

第一个字节将被视为NUL终止符。不会发生倒车。

UTF-16小端点:

原件:

0x61、0x00、0xf1、0x00、0x6f、0x00、0x00、0x00

第二个字节将被视为NUL终止符。结果将是0x61、0x00,一个包含“a”字符的字符串。


阅读克尼汉和里奇的著作

#include <string.h>

void reverse(char s[])
{
    int length = strlen(s) ;
    int c, i, j;

    for (i = 0, j = length - 1; i < j; i++, j--)
    {
        c = s[i];
        s[i] = s[j];
        s[j] = c;
    }
}
#包括
无效反向(字符s[])
{
整数长度=strlen(s);
int c,i,j;
对于(i=0,j=length-1;i
如果您使用GLib,它有两个功能,我喜欢Evgeny的K&R答案。不过,看到使用指针的版本还是不错的。否则,本质上是一样的:

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

char *reverse(char *str) {
    if( str == NULL || !(*str) ) return NULL;
    int i, j = strlen(str)-1;
    char *sallocd;
    sallocd = malloc(sizeof(char) * (j+1));
    for(i=0; j>=0; i++, j--) {
        *(sallocd+i) = *(str+j);
    }
    return sallocd;
}

int main(void) {
    char *s = "a man a plan a canal panama";
    char *sret = reverse(s);
    printf("%s\n", reverse(sret));
    free(sret);
    return 0;
}
#包括
#包括
#包括
字符*反向(字符*str){
如果(str==NULL | |!(*str))返回NULL;
inti,j=strlen(str)-1;
沙洛德;
sallocd=malloc(sizeof(char)*(j+1));
对于(i=0;j>=0;i++,j--){
*(sallocd+i)=*(str+j);
}
萨洛德回归;
}
内部主(空){
char*s=“巴拿马运河计划”;
char*sret=反向;
printf(“%s\n”,反向(sret));
免费(sret);
返回0;
}

已经有一段时间了,我不记得是哪本书教了我这个算法,但我认为它非常巧妙,也很容易理解:

char input[] = "moc.wolfrevokcats";

int length = strlen(input);
int last_pos = length-1;
for(int i = 0; i < length/2; i++)
{
    char tmp = input[i];
    input[i] = input[last_pos - i];
    input[last_pos - i] = tmp;
}

printf("%s\n", input);
char input[]=“moc.wolfrevokcats”;
int length=strlen(输入);
int last_pos=长度-1;
对于(int i=0;i
此算法的可视化,由以下人员提供:


递归函数,用于就地反转字符串(无额外缓冲区,malloc)

简短、性感的代码。糟糕,糟糕的堆栈使用

#include <stdio.h>

/* Store the each value and move to next char going down
 * the stack. Assign value to start ptr and increment 
 * when coming back up the stack (return).
 * Neat code, horrible stack usage.
 *
 * val - value of current pointer.
 * s - start pointer
 * n - next char pointer in string.
 */
char *reverse_r(char val, char *s, char *n)
{
    if (*n)
        s = reverse_r(*n, s, n+1);
   *s = val;
   return s+1;
}

/*
 * expect the string to be passed as argv[1]
 */
int main(int argc, char *argv[])
{
    char *aString;

    if (argc < 2)
    {
        printf("Usage: RSIP <string>\n");
        return 0;
    }

    aString = argv[1];
    printf("String to reverse: %s\n", aString );

    reverse_r(*aString, aString, aString+1); 
    printf("Reversed String:   %s\n", aString );

    return 0;
}
#包括
/*存储每个值并移动到下一个字符
*那一堆。为启动ptr和增量赋值
*返回堆栈时(返回)。
*整洁的代码,可怕的堆栈使用。
*
*val—当前指针的值。
*s开始指针
*n-字符串中的下一个字符指针。
*/
char*reverse\u r(char val,char*s,char*n)
{
如果(*n)
s=反向(n,s,n+1);
*s=val;
返回s+1;
}
/*
*希望字符串作为argv[1]传递
*/
int main(int argc,char*argv[])
{
炭化;
如果(argc<2)
{
公共关系
void strrev(char *str)
{
    if (str == NULL)
        return;
    std::reverse(str, str + strlen(str));
}
#include <string.h>

void reverse(char s[])
{
    int length = strlen(s) ;
    int c, i, j;

    for (i = 0, j = length - 1; i < j; i++, j--)
    {
        c = s[i];
        s[i] = s[j];
        s[j] = c;
    }
}
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

char *reverse(char *str) {
    if( str == NULL || !(*str) ) return NULL;
    int i, j = strlen(str)-1;
    char *sallocd;
    sallocd = malloc(sizeof(char) * (j+1));
    for(i=0; j>=0; i++, j--) {
        *(sallocd+i) = *(str+j);
    }
    return sallocd;
}

int main(void) {
    char *s = "a man a plan a canal panama";
    char *sret = reverse(s);
    printf("%s\n", reverse(sret));
    free(sret);
    return 0;
}
char input[] = "moc.wolfrevokcats";

int length = strlen(input);
int last_pos = length-1;
for(int i = 0; i < length/2; i++)
{
    char tmp = input[i];
    input[i] = input[last_pos - i];
    input[last_pos - i] = tmp;
}

printf("%s\n", input);
#include <stdio.h>

/* Store the each value and move to next char going down
 * the stack. Assign value to start ptr and increment 
 * when coming back up the stack (return).
 * Neat code, horrible stack usage.
 *
 * val - value of current pointer.
 * s - start pointer
 * n - next char pointer in string.
 */
char *reverse_r(char val, char *s, char *n)
{
    if (*n)
        s = reverse_r(*n, s, n+1);
   *s = val;
   return s+1;
}

/*
 * expect the string to be passed as argv[1]
 */
int main(int argc, char *argv[])
{
    char *aString;

    if (argc < 2)
    {
        printf("Usage: RSIP <string>\n");
        return 0;
    }

    aString = argv[1];
    printf("String to reverse: %s\n", aString );

    reverse_r(*aString, aString, aString+1); 
    printf("Reversed String:   %s\n", aString );

    return 0;
}
#include <stdio.h>
#include <strings.h>

int main(int argc, char **argv) {

  char *reverse = argv[argc-1];
  char *left = reverse;
  int length = strlen(reverse);
  char *right = reverse+length-1;
  char temp;

  while(right-left>=1){

    temp=*left;
    *left=*right;
    *right=temp;
    ++left;
    --right;

  }

  printf("%s\n", reverse);

}
str = std::string(str.rbegin(), str.rend());
char* reverse(char* s)
{
    char* beg = s, *end = s, tmp;
    while (*end) end++;
    while (end-- > beg)
    { 
        tmp  = *beg; 
        *beg++ = *end;  
        *end =  tmp;
    }
    return s;
} // fixed: check history for details, as those are interesting ones
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>

unsigned char * utf8_reverse(const unsigned char *, int);
void assert_true(bool);

int main(void)
{
    unsigned char str[] = "mañana mañana";
    unsigned char *ret = utf8_reverse(str,  strlen((const char *) str) + 1);

    printf("%s\n", ret);
    assert_true(0 == strncmp((const char *) ret, "anãnam anañam", strlen("anãnam anañam") + 1));

    free(ret);

    return EXIT_SUCCESS;
}

unsigned char * utf8_reverse(const unsigned char *str, int size)
{
    unsigned char *ret = calloc(size, sizeof(unsigned char*));
    int ret_size = 0;
    int pos = size - 2;
    int char_size = 0;

    if (str ==  NULL) {
        fprintf(stderr, "failed to allocate memory.\n");
        exit(EXIT_FAILURE);
    }

    while (pos > -1) {

        if (str[pos] < 0x80) {
            char_size = 1;
        } else if (pos > 0 && str[pos - 1] > 0xC1 && str[pos - 1] < 0xE0) {
            char_size = 2;
        } else if (pos > 1 && str[pos - 2] > 0xDF && str[pos - 2] < 0xF0) {
            char_size = 3;
        } else if (pos > 2 && str[pos - 3] > 0xEF && str[pos - 3] < 0xF5) {
            char_size = 4;
        } else {
            char_size = 1;
        }

        pos -= char_size;
        memcpy(ret + ret_size, str + pos + 1, char_size);
        ret_size += char_size;
    }    

    ret[ret_size] = '\0';

    return ret;
}

void assert_true(bool boolean)
{
    puts(boolean == true ? "true" : "false");
}
void showReverse(char s[], int length)
{
    printf("Reversed String without storing is ");
    //could use another variable to test for length, keeping length whole.
    //assumes contiguous memory
    for (; length > 0; length--)
    {
        printf("%c", *(s+ length-1) );
    }
    printf("\n");
}
void StringReverser(std::string *original)
{
  int eos = original->length() - 1;
  while (eos > 0) {
    char c = (*original)[0];
    int characterBytes;
    switch( (c & 0xF0) >> 4 ) {
    case 0xC:
    case 0xD: /* U+000080-U+0007FF: two bytes. */
      characterBytes = 2;
      break;
    case 0xE: /* U+000800-U+00FFFF: three bytes. */
      characterBytes = 3;
      break;
    case 0xF: /* U+010000-U+10FFFF: four bytes. */
      characterBytes = 4;
      break;
    default:
      characterBytes = 1;
      break;
    }

    for (int i = 0; i < characterBytes; i++) {
      original->insert(eos+i, 1, (*original)[i]);
    }
    original->erase(0, characterBytes);
    eos -= characterBytes;
  }
}
void reverseString(vector<char>& s) {
        int l = s.size();
        char ch ;
        int i = 0 ;
        int j = l-1;
        while(i < j){
                s[i] = s[i]^s[j];
                s[j] = s[i]^s[j];
                s[i] = s[i]^s[j];
                i++;
                j--;
        }
        for(char c : s)
                cout <<c ;
        cout<< endl;
}