【问题标题】:C++ program not returning a Value (Functions)C++ 程序不返回值(函数)
【发布时间】:2021-04-14 03:56:44
【问题描述】:

我想编写一个程序,创建一个函数,将两个字符串连接成一个字符串。但是,我的程序没有返回任何值。

#include <iostream>
#include <cstring>
#include <string>

using namespace std;

char* my_str_cat( char* s1, char* s2, char* combined ){
   for(int i = 0;i<strlen(s1);i++){
       combined[i]=s1[i];
   }
   for (int j=0;j<strlen(s2);j++){
       combined[strlen(s1)+j]=s2[j];
   }
   return combined;
}

int main(){
   char s1[100];
   char s2[100];
   char** combined = new char*;
   cout<<"Enter s1: "<<endl;
   cin.getline(s1,100);
   cout<<s1<<endl;
   cout<<"Enter s2: "<<endl;
   cin.getline(s2,100);
   my_str_cat(s1,s2,*combined);
   delete combined;
   
   return 0;
}

【问题讨论】:

  • 因为您从不为*combined 保留任何内存,这可能应该是char *,而不是char**
  • 为什么combinedchar** 开头?为什么不是普通的char*?或者更好的是,std::string?
  • std::string 有一个 operator+ 连接。如果您想将此作为练习,则需要为组合字符串提供一些字符,而不仅仅是指向字符的指针
  • 对了,为什么不写一些代码来检查my_str_cat的结果呢?
  • 当我尝试 char* 时出现错误

标签: c++ dynamic-memory-allocation c-strings string-concatenation function-definition


【解决方案1】:

此声明

char** combined = new char*;

声明char ** 类型的指针,该指针指向为char * 类型的对象分配的内存。

在此调用中取消引用此指针

my_str_cat(s1,s2,*combined);

char * 类型的未初始化指针传递给函数my_str_cat

在函数内部,这个未初始化的指针用于访问导致未定义行为的内存。

您需要为字符数组分配足够大的内存,以存储两个连接的 C 字符串,形成一个新的 C 字符串。

您可以在函数本身内分配内存。

该函数可以如下面的演示程序所示。

#include <iostream>
#include <iomanip>
#include <cstring>

char * my_str_cat( const char *s1, const char *s2 )
{
    size_t n1 = std::strlen( s1 );
    
    char * result = new char[n1 + std::strlen( s2 ) + 1];
    
    std::strcpy( std::strcpy( result, s1 ) + n1, s2 );
    
    return result;
}

int main() 
{
    const size_t N = 100;
    char s1[N];
    char s2[N];
    
    std::cout << "Enter s1: ";
    
    std::cin.getline( s1, sizeof( s1 ) );
    
    std::cout << "Enter s2: ";
    
    std::cout << std::noskipws;
    
    std::cin.getline( s2, sizeof( s2 ) );
    
    char *combined = my_str_cat( s1, s2 );
    
    std::cout << combined << '\n';
    
    delete []combined;
    
    return 0;
}

程序输出可能看起来像

Enter s1: Hello
Enter s2:  World!
Hello World!

另一种声明和定义函数的方法是,当函数的用户负责将结果字符数组提供给将包含两个连接字符串的函数时。

例如

#include <iostream>
#include <iomanip>
#include <cstring>

char * my_str_cat( char *result, const char *s1, const char *s2 )
{
    return std::strcat( std::strcpy( result, s1 ) , s2 );
}

int main() 
{
    const size_t N = 100;
    char s1[N];
    char s2[N];
    
    std::cout << "Enter s1: ";
    
    std::cin.getline( s1, sizeof( s1 ) );
    
    std::cout << "Enter s2: ";
    
    std::cout << std::noskipws;
    
    std::cin.getline( s2, sizeof( s2 ) );
    
    char *combined = new char[std::strlen( s1 ) + std::strlen( s2 ) + 1];

    std::cout << my_str_cat( combined, s1, s2 ) << '\n';
    
    delete []combined;
    
    return 0;
}

程序输出看起来可能与之前的演示程序显示的方式相同

Enter s1: Hello
Enter s2:  World!
Hello World!

不使用标准字符串函数,只使用循环函数可以通过以下方式定义。

char * my_str_cat( char *result, const char *s1, const char *s2 )
{
    char *p = result;
    
    while ( *s1 ) *p++ = *s1++;
    
    while ( ( *p++ = *s2++ ) );

    return result;
}

【讨论】:

  • ( result, s1 ) + n1 这是做什么的?
  • @Agitated_Mouse 看来你的意思是表达式 std::strcpy(result, s1) + n1。函数 strcpy 返回一个指向字符数组结果的第一个字符的指针。但是我们需要将第二个字符串添加到第一个字符串的末尾。所以我们将目标指针计算为初始指针加上复制的第一个字符串的长度。
  • 所以只是为了澄清 `strcpy(result,s1)+n1,s2) 首先将 s1 复制到结果中,但是我们如何添加 n1(是否因为 s1 是一个数组?),然后添加n1 s2 被复制
  • @Agitated_Mouse 是指针算法。函数 strcpy 返回指向数组结果第一个字符的指针。但是我们必须在地址 &result[n1] 处复制第二个字符串,它与 result + n1 相同。
【解决方案2】:

首先,它(将)返回一个值,只是没有分配给任何东西。这样做:

*combined = my_str_cat(s1,s2,*combined);

也可以通过引用组合,或者全部不通过。

但它不会导致它因段错误而崩溃,因为您在 s1 未初始化时引用了 s1[i]。 我要纠正 C 风格的问题,因为你的代码实际上只是带有香料的 C:

#include <iostream>
#include <cstdlib>
#include <cstring>
#include <string>

using namespace std;
    
void my_str_cat( char* s1, char* s2, char* &combined){
    int len = strlen(s1);
    combined = (char*)calloc(1, (len + strlen(s2)));
    strcpy(combined, s1);
    strcpy(combined + len, s2);
}

int main(){
   char s1[100];
   char s2[100];
   char* combined;
   cout<<"Enter s1: " << endl;
   cin.getline(s1,100);
   cout<<s1<<endl;
   cout<<"Enter s2: " << endl;
   cin.getline(s2,100);
   my_str_cat(s1,s2, combined);
   cout << combined << endl;
   delete combined;
   
   return 0;
}

(虽然这行得通,但我在写这篇文章时感觉错过了一些东西。如果你知道,请告诉我这是什么。)

【讨论】:

    猜你喜欢
    • 2019-03-18
    • 2017-08-12
    • 1970-01-01
    • 1970-01-01
    • 2022-07-21
    • 1970-01-01
    • 2016-08-28
    • 1970-01-01
    • 2015-12-28
    相关资源
    最近更新 更多