循环反转C中的字符串
loop to reverse string in C
所以我四处查看了 SO,但找不到可以回答我的问题的代码。我编写了一个函数,该函数应该将字符串作为 cmd 行中的输入进行反转。这是函数:
void reverse (char string[]) {
int x;
int i = 0;
char line[strlen(string)];
for (x = strlen(string) - 1; x > 0; x--) {
char tmp = string[x];
line[i] = tmp;
i++;
}
string = line;
}
当我调用 reverse() 函数时,字符串保持不变。即,'abc' 仍然是 'abc'
如果需要更多信息或问题不合适,请告诉我。
谢谢!!
代码中的最后一行什么也没做
string = line;
参数按值传递,因此如果您更改它们的值,那只是函数的局部值。指针是它们指向的内存地址的值。如果你想修改函数传递的指针,你需要取一个指向那个指针的指针。
这是一个简短的例子,说明如何做到这一点。
void reverse (char **string) {
char line = malloc(strlen(*string) + 1);
//automatic arrays are deallocated once the function ends
//so line needs to be dynamically or statically allocated
// do something to line
*string = line;
}
这个明显的问题是您可以用静态内存初始化字符串,然后此方法将用动态内存替换静态内存,然后您必须释放动态内存。这在功能上没有任何问题,只是有点危险,因为不小心释放字符串文字是非法的。
char *test = "hello";
reverse(test);
free(test); //this is pretty scary
另外,如果test被分配为动态内存,指向它的指针就会丢失,然后就会成为内存泄漏。
您正在声明您的 line
数组一个 char
更短,请记住末尾的 null
。
还有一点,应该是for (x = strlen(string) - 1; x >= 0; x--)
,因为需要复制0
处的字符。
void reverse (char string[]) {
int x;
int i = 0;
char line[strlen(string) + 1];
for (x = strlen(string) - 1; x >= 0; x--) {
char tmp = string[x];
line[i] = tmp;
i++;
}
for(x = 0; x < strlen(string); x++)
{
string[x] = line[x];
}
}
请注意,当传递空字符串或字符串文字(如 Bobby Sacamano 所说)时,此函数将导致天启。
您可能可以做的建议:void reverse(char source[], char[] dest)
并检查源字符串是否为空。
我认为你的回答几乎是正确的。您实际上不需要为行中的空字符添加额外的插槽。您只需要进行两个小改动:
- 将程序底部的赋值语句更改为 memcpy。
- 将循环条件更改为<-
所以,你的正确代码是这样的:
void reverse (char string[]) {
int x;
int i = 0;
char line[strlen(string)];
for (x = strlen(string) - 1; x >= 0; x--) {
char tmp = string[x];
line[i] = tmp;
i++;
}
memcpy(string, line, sizeof(char) * strlen(line));
}
既然要反转字符串,首先要决定是要反转字符串的副本,还是就地反转字符串(就地)。由于您在 'C' 上下文中询问过这个问题,假设您的意思是更改现有字符串(反转现有字符串)并在调用函数中复制字符串,如果您想保留原始字符串。
您将需要字符串库
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
数组索引有效,这个版本采用了这种方法,
/* this first version uses array indexing */
char*
streverse_a(char string[])
{
int len; /*how big is your string*/
int ndx; /*because 'i' is hard to search for*/
char tmp; /*hold character to swap*/
if(!string) return(string); /*avoid NULL*/
if( (len=strlen(string)) < 2 ) return(string); /*one and done*/
for( ndx=0; ndx<len/2; ndx++ ) {
tmp=string[ndx];
string[ndx]=string[len-1-ndx];
string[len-1-ndx]=tmp;
}
return(string);
}
但是你可以用指针做同样的事情,
/* this is how K&R would write the function with pointers */
char*
streverse(char* sp)
{
int len, ndx; /*how big is your string */
char tmp, *bp, *ep; /*pointers to begin/end, swap temporary*/
if(!sp) return(sp); /*avoid NULL*/
if( (len=strlen(bp=sp)) < 2 ) return(sp); /*one and done*/
for( ep=bp+len-1; bp<ep; bp++, ep-- ) {
tmp=*bp; *bp=*ep; *ep=tmp; /*swap*/
}
return(sp);
}
(不,真的,编译器不会因为返回void而少收费。)
并且因为您总是测试您的代码,
char s[][100] = {
"", "A", "AB", "ABC", "ABCD", "ABCDE",
"hello, world", "goodbye, cruel world", "pwnz0r3d", "enough"
};
int
main()
{
/* suppose your string is declared as 'a' */
char a[100];
strcpy(a,"reverse string");
/*make a copy of 'a', declared the same as a[]*/
char b[100];
strcpy(b,a);
streverse_a(b);
printf("a:%s, r:%s\n",a,b);
/*duplicate 'a'*/
char *rp = strdup(a);
streverse(rp);
printf("a:%s, r:%s\n",a,rp);
free(rp);
int ndx;
for( ndx=0; ndx<10; ++ndx ) {
/*make a copy of 's', declared the same as s[]*/
char b[100];
strcpy(b,s[ndx]);
streverse_a(b);
printf("s:%s, r:%s\n",s[ndx],b);
/*duplicate 's'*/
char *rp = strdup(s[ndx]);
streverse(rp);
printf("s:%s, r:%s\n",s[ndx],rp);
free(rp);
}
}
所以我四处查看了 SO,但找不到可以回答我的问题的代码。我编写了一个函数,该函数应该将字符串作为 cmd 行中的输入进行反转。这是函数:
void reverse (char string[]) {
int x;
int i = 0;
char line[strlen(string)];
for (x = strlen(string) - 1; x > 0; x--) {
char tmp = string[x];
line[i] = tmp;
i++;
}
string = line;
}
当我调用 reverse() 函数时,字符串保持不变。即,'abc' 仍然是 'abc'
如果需要更多信息或问题不合适,请告诉我。
谢谢!!
代码中的最后一行什么也没做
string = line;
参数按值传递,因此如果您更改它们的值,那只是函数的局部值。指针是它们指向的内存地址的值。如果你想修改函数传递的指针,你需要取一个指向那个指针的指针。
这是一个简短的例子,说明如何做到这一点。
void reverse (char **string) {
char line = malloc(strlen(*string) + 1);
//automatic arrays are deallocated once the function ends
//so line needs to be dynamically or statically allocated
// do something to line
*string = line;
}
这个明显的问题是您可以用静态内存初始化字符串,然后此方法将用动态内存替换静态内存,然后您必须释放动态内存。这在功能上没有任何问题,只是有点危险,因为不小心释放字符串文字是非法的。
char *test = "hello";
reverse(test);
free(test); //this is pretty scary
另外,如果test被分配为动态内存,指向它的指针就会丢失,然后就会成为内存泄漏。
您正在声明您的 line
数组一个 char
更短,请记住末尾的 null
。
还有一点,应该是for (x = strlen(string) - 1; x >= 0; x--)
,因为需要复制0
处的字符。
void reverse (char string[]) {
int x;
int i = 0;
char line[strlen(string) + 1];
for (x = strlen(string) - 1; x >= 0; x--) {
char tmp = string[x];
line[i] = tmp;
i++;
}
for(x = 0; x < strlen(string); x++)
{
string[x] = line[x];
}
}
请注意,当传递空字符串或字符串文字(如 Bobby Sacamano 所说)时,此函数将导致天启。
您可能可以做的建议:void reverse(char source[], char[] dest)
并检查源字符串是否为空。
我认为你的回答几乎是正确的。您实际上不需要为行中的空字符添加额外的插槽。您只需要进行两个小改动:
- 将程序底部的赋值语句更改为 memcpy。
- 将循环条件更改为<-
所以,你的正确代码是这样的:
void reverse (char string[]) {
int x;
int i = 0;
char line[strlen(string)];
for (x = strlen(string) - 1; x >= 0; x--) {
char tmp = string[x];
line[i] = tmp;
i++;
}
memcpy(string, line, sizeof(char) * strlen(line));
}
既然要反转字符串,首先要决定是要反转字符串的副本,还是就地反转字符串(就地)。由于您在 'C' 上下文中询问过这个问题,假设您的意思是更改现有字符串(反转现有字符串)并在调用函数中复制字符串,如果您想保留原始字符串。
您将需要字符串库
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
数组索引有效,这个版本采用了这种方法,
/* this first version uses array indexing */
char*
streverse_a(char string[])
{
int len; /*how big is your string*/
int ndx; /*because 'i' is hard to search for*/
char tmp; /*hold character to swap*/
if(!string) return(string); /*avoid NULL*/
if( (len=strlen(string)) < 2 ) return(string); /*one and done*/
for( ndx=0; ndx<len/2; ndx++ ) {
tmp=string[ndx];
string[ndx]=string[len-1-ndx];
string[len-1-ndx]=tmp;
}
return(string);
}
但是你可以用指针做同样的事情,
/* this is how K&R would write the function with pointers */
char*
streverse(char* sp)
{
int len, ndx; /*how big is your string */
char tmp, *bp, *ep; /*pointers to begin/end, swap temporary*/
if(!sp) return(sp); /*avoid NULL*/
if( (len=strlen(bp=sp)) < 2 ) return(sp); /*one and done*/
for( ep=bp+len-1; bp<ep; bp++, ep-- ) {
tmp=*bp; *bp=*ep; *ep=tmp; /*swap*/
}
return(sp);
}
(不,真的,编译器不会因为返回void而少收费。)
并且因为您总是测试您的代码,
char s[][100] = {
"", "A", "AB", "ABC", "ABCD", "ABCDE",
"hello, world", "goodbye, cruel world", "pwnz0r3d", "enough"
};
int
main()
{
/* suppose your string is declared as 'a' */
char a[100];
strcpy(a,"reverse string");
/*make a copy of 'a', declared the same as a[]*/
char b[100];
strcpy(b,a);
streverse_a(b);
printf("a:%s, r:%s\n",a,b);
/*duplicate 'a'*/
char *rp = strdup(a);
streverse(rp);
printf("a:%s, r:%s\n",a,rp);
free(rp);
int ndx;
for( ndx=0; ndx<10; ++ndx ) {
/*make a copy of 's', declared the same as s[]*/
char b[100];
strcpy(b,s[ndx]);
streverse_a(b);
printf("s:%s, r:%s\n",s[ndx],b);
/*duplicate 's'*/
char *rp = strdup(s[ndx]);
streverse(rp);
printf("s:%s, r:%s\n",s[ndx],rp);
free(rp);
}
}