在某些范围内无法在 C++ 中正确 return 字符串
Unable to return string properly in C++ for some range
我编写了一个 C++ 程序,使用指向 return 字符串反转的指针和函数。当函数 rev 中的范围 char p[] 很低,比如 25(小于。145)时,输出就像 ►↕☻ ☺♠♥,它不反转,当范围高于 145 时,它工作正常在 gcc 中,对于 Borland TurboC,最小范围必须是 65,否则程序会打印奇怪的值而不是反转它。
#include<iostream>
#include<conio.h>
#include<string.h>
#include<stdio.h>
using namespace std;
int main()
{
char str[20];
int l;
char* p1;
//clrscr();
gets(str);
l=strlen(str);
char* rev(char*,int);
p1=rev(str,l);
puts(p1);
return 0;
//getch();
}
char * rev(char* a,int l1)
{
char p[25]; // HERE: higher than 146 is working
int c=0;
for(l1=l1-1;l1>=0;l1--)
{
p[c]=a[l1];
c++;
}
p[c]=NULL;
return(p);
}
当你声明时
char p[25]
in 函数 rev 仅在本地声明。当您到达函数末尾时,所有局部变量都将被删除(包括数组 p)。解决此问题的最简单方法是将 char p[25] 更改为:
char *p = new char[25]
但请注意,如果您在不再需要内存时不释放内存,这可能会导致内存泄漏。我建议您使用 std::string 或查看一些内置函数,例如 [=24] 中的 strrev =].
在函数rev
中数组char p[25];
是函数的局部对象。函数退出后不会存活,一般可以销毁,也就是它占用的内存可以被其他对象或函数覆盖。
所以返回的指针指向这个数组的第一个字符是无效的,程序有未定义的行为。
不清楚为什么函数中的数组定义的大小等于幻数 25。如果传递给函数的第二个参数将大于 25,那么再次出现问题,因为内存将超出数组覆盖。
还有就是功能设计的不好。函数反转字符串 "in place" 或以相反顺序复制目标数组中的源数组,在这种情况下,目标数组必须是函数参数。
并且在 C++ 程序中使用 C IO 函数是一个坏主意。此外,函数 gets
是不安全的,C 标准不再支持它。
函数可以看成下面的样子
#include <iostream>
#include <cstring>
char * reverse_copy( char *s1, const char *s2 )
{
size_t n = std::strlen( s2 );
size_t i = 0;
for ( ; i < n; i++ ) s1[i] = s2[n - i - 1];
s1[i] = '[=10=]';
return s1;
}
int main()
{
const size_t N = 20;
char str1[N];
char str2[N];
std::cin.getline( str2, N );
std::cout << str2 << std::endl;
std::cout << ::reverse_copy( str1, str2 ) << std::endl;
}
如果要输入词组
Hello, Priyal Kumar
那么程序输出将是
Hello, Priyal Kumar
ramuK layirP ,olleH
我编写了一个 C++ 程序,使用指向 return 字符串反转的指针和函数。当函数 rev 中的范围 char p[] 很低,比如 25(小于。145)时,输出就像 ►↕☻ ☺♠♥,它不反转,当范围高于 145 时,它工作正常在 gcc 中,对于 Borland TurboC,最小范围必须是 65,否则程序会打印奇怪的值而不是反转它。
#include<iostream>
#include<conio.h>
#include<string.h>
#include<stdio.h>
using namespace std;
int main()
{
char str[20];
int l;
char* p1;
//clrscr();
gets(str);
l=strlen(str);
char* rev(char*,int);
p1=rev(str,l);
puts(p1);
return 0;
//getch();
}
char * rev(char* a,int l1)
{
char p[25]; // HERE: higher than 146 is working
int c=0;
for(l1=l1-1;l1>=0;l1--)
{
p[c]=a[l1];
c++;
}
p[c]=NULL;
return(p);
}
当你声明时
char p[25]
in 函数 rev 仅在本地声明。当您到达函数末尾时,所有局部变量都将被删除(包括数组 p)。解决此问题的最简单方法是将 char p[25] 更改为:
char *p = new char[25]
但请注意,如果您在不再需要内存时不释放内存,这可能会导致内存泄漏。我建议您使用 std::string 或查看一些内置函数,例如 [=24] 中的 strrev =].
在函数rev
中数组char p[25];
是函数的局部对象。函数退出后不会存活,一般可以销毁,也就是它占用的内存可以被其他对象或函数覆盖。
所以返回的指针指向这个数组的第一个字符是无效的,程序有未定义的行为。
不清楚为什么函数中的数组定义的大小等于幻数 25。如果传递给函数的第二个参数将大于 25,那么再次出现问题,因为内存将超出数组覆盖。
还有就是功能设计的不好。函数反转字符串 "in place" 或以相反顺序复制目标数组中的源数组,在这种情况下,目标数组必须是函数参数。
并且在 C++ 程序中使用 C IO 函数是一个坏主意。此外,函数 gets
是不安全的,C 标准不再支持它。
函数可以看成下面的样子
#include <iostream>
#include <cstring>
char * reverse_copy( char *s1, const char *s2 )
{
size_t n = std::strlen( s2 );
size_t i = 0;
for ( ; i < n; i++ ) s1[i] = s2[n - i - 1];
s1[i] = '[=10=]';
return s1;
}
int main()
{
const size_t N = 20;
char str1[N];
char str2[N];
std::cin.getline( str2, N );
std::cout << str2 << std::endl;
std::cout << ::reverse_copy( str1, str2 ) << std::endl;
}
如果要输入词组
Hello, Priyal Kumar
那么程序输出将是
Hello, Priyal Kumar
ramuK layirP ,olleH