[英]Why is my function to reverse string in c not working?
我正在编写一些 C 代码,用户在其中输入所需的字符串大小,然后将字符串反转然后打印(而不是反向打印。)我还想提一下,我不想使用外部库,重点是能够手动完成。 我使用动态 memory 分配来创建用户输入大小的字符串,并称为“反向数组”function。 在调用 function 之前一切正常。 我反转字符串的方法遵循与反转普通数组相同的原则,但不是移动整数,而是移动字符。 你能向我解释我做错了什么吗?
我的代码:
#include <stdio.h>
#include <stdlib.h>
int RvsArr(char *Str, int end)
{
int start = 0;
char tmp;
while (start < end)
{
tmp = Str[start];
Str[start] = Str[end];
Str[end] = tmp;
start++;
end--;
}
printf("%s", Str);
return 0;
}
int main()
{
int ArrSz;
printf("Please enter array size: ");
scanf("%i", &ArrSz);
char *Str;
Str = (char *)malloc(ArrSz * sizeof(char));
printf("Please enter your string: ");
scanf("%s", Str);
RvsArr(Str, ArrSz);
free(Str);
return 0;
}
您需要反转实际的字符串,而不是整个缓冲区。
char *RvsArr(char* Str)
{
char *end, *wrk = Str;
char tmp;
if(wrk && *wrk)
{
end = Str + strlen(wrk) - 1;
while(wrk < end)
{
tmp = *wrk;
*wrk++ = *end;
*end-- = tmp;
}
}
return Str;
}
int main()
{
int ArrSz;
printf("Please enter array size: ");
scanf(" %i", &ArrSz);
char* Str;
Str = malloc(ArrSz * sizeof(char));
printf("Please enter your string: ");
scanf(" %s", Str);
printf("\n`%s`\n", RvsArr(Str));
free(Str);
return 0;
}
对于初学者,用户可以输入一个字符串,其大小可以小于存储该字符串的动态分配的字符数组的大小。
所以传递数组的大小没有意义。 数组的大小与输入的字符串的大小不同。
此表达式Str[end]
在 while 循环的第一次迭代中访问超出分配数组的 memory。
而且返回类型int
也没有任何意义。
除此之外 function 不应该 output 任何东西。 function 的调用者将决定 output 结果字符串与否。
注意这个电话
scanf("%s", Str);
不安全。 最好使用 function fgets。 例如
fgets( Str, ArrSz, stdin );
在这种情况下,您需要将 function 可以 append 的新行字符'\n'
删除到输入的字符串中。
在不使用标准字符串函数的情况下,function 可以按以下方式定义,如下面的演示程序所示。 function 不是无意义的返回类型int
,而是返回一个指向反转字符串的第一个字符的指针。
#include <stdio.h>
char * RvsArr( char *s )
{
char *last = s;
while ( *last ) ++last;
if ( last != s )
{
for ( char *first = s; first < --last; ++first )
{
char c = *first;
*first = *last;
*last = c;
}
}
return s;
}
int main(void)
{
char s[] = "Hello World!";
puts( s );
puts( RvsArr( s ) );
return 0;
}
程序 output 是
Hello World!
!dlroW olleH
如果允许您使用标准字符串函数,则 function RvsArr 可以如下所示(前提是包含 header <string.h>
)
char * RvsArr( char *s )
{
char *last = s + strlen( s );
if ( last != s )
{
for ( char *first = s; first < --last; ++first )
{
char c = *first;
*first = *last;
*last = c;
}
}
return s;
}
字符 arrays 或 c 中的字符串(通常称为)需要一个额外的字节来存储 null 字符( '\o'
或0
)以指示字符串的结尾。 您可以在数组中存储ArrSz - 1
字符,并且ArrSz
字节存储终止字符( '\o'
或0
)。
int RvsArr(char* Str, int end)
{
if (Str == 0 || end <= 1)
return 0;
int start = 0;
char tmp;
while(start < end)
{
tmp = Str[start];
Str[start] = Str[--end]; // pre decrement the counter to last char
Str[end] = tmp;
start++;
}
printf("%s", Str);
return 0;
}
或其他版本
int RvsArr(char* Str, int end)
{
if (Str == 0 || end <= 1)
return 0;
int start = 0;
int last = end - 1;
char tmp;
while(start < last)
{
tmp = Str[start];
Str[start] = Str[last];
Str[last] = tmp;
start++;
last--;
}
printf("%s", Str);
return 0;
}
主要 function 的一些变化是
int main()
{
int ArrSz;
printf("Please enter array size: ");
scanf("%i", &ArrSz);
char *Str;
Str = (char *)malloc(ArrSz * sizeof(char));
printf("Please enter your string: ");
scanf("%s", Str);
Str[ArrSz] = '\0'; // Here we have no control on how many characters are read, scan is a security vulnerability becuse of this
printf("Input=%s, len=%d\n", Str, strlen(Str));
RvsArr(Str, strlen(Str));
free(Str);
return 0;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.