我有一个问题,不要编译这段代码,而是执行这个程序。当我在终端中运行它打印前2 cout
然后程序停止工作,窗口上的屏幕告诉你,我认为问题是strcat
。
我使用的是DEVC ++,我有Windows 7专业版。
#include <iostream>
#include <string>
#include <cstdlib>
#include <string.h>
using namespace std;
int main() {
char* cambia[] = {"ciao "};
char* c[] = {"mondo"};
cout << "*c: " << *c << endl;
cout << "*cambia: " << *cambia << endl;
strcat( *cambia, *c );
cout << "*cambia: " << *cambia << endl;
}
答案 0 :(得分:2)
如果你不是必须的话,你不会在C ++中使用strcat()
(例如,在维护遗留代码和触摸尽可能少的东西时)。
使用std::string
及其成员函数(如find
或substr
)执行简单任务,string streams或Boost libraries进行更复杂的字符串拆分。
无论如何,请远离strcat()
。
答案 1 :(得分:1)
这里的问题是您正在尝试写入只读字符串存储。
这些声明:
char* cambia[] = {"ciao "};
char* c[] = {"mondo"};
声明两个数组,每个数组都有一个常量字符串成员。 "ciao "
和"mondo"
位于只读内存中。
因此,当您致电strcat(*cambia, *c)
时,您正试图将"mondo"
写入"ciao "
的末尾。这不仅写入只读内存,而且还写入为字符串给出的内存空间 - char
字符串中只有6 "ciao "
的空格,并且您正在尝试添加另外5到结束。
解决方案是为每个字符串保留一些空间。有多种方法可以做到这一点。这是一个简单的:
char acambia[20] = "ciao "; // Space for 20 characters.
char* cambia[] = { acambia };
对于coruse,不使用额外的间接级别会使其更简单:
char cambia[20] = "ciao ";
char c[] = "mondo";
strcat(cambia, c);
会达到正确的结果。
答案 2 :(得分:1)
方法strcat()将第二个参数的字符串添加到您提交给第一个参数的缓冲区。
首先,缓冲区必须是可写的。在您的示例中,您将字符串文字作为缓冲区传递。当然,字符串文字是只读的。但即使这样,字符串文字也没有可以添加新字符串的空余空间。
不是修复代码,而是让我向您展示一些如何在C ++和C中连接字符串的正确示例。
此示例向您展示如何连接两个C ++字符串:
#include <iostream>
#include <string>
int main(int argc, const char * argv[])
{
// Create a new C++ string with an initial text.
std::string result = "First string part ";
std::cout << "Result: " << result << std::endl;
// Add some text
std::string textToAppend = "and the second part";
result.append(textToAppend);
std::cout << "Result: " << result << std::endl;
return 0;
}
以下示例向您展示如何在C中连接两个字符串:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, const char * argv[])
{
// The two texts to concat
const char *firstText = "This is the first text ";
const char *secondText = "and this is the second one";
// A buffer which is large enough for the operation.
const int bufferSize = 1024;
char buffer[bufferSize];
// Copy the initial text into the buffer.
strncpy(buffer, firstText, bufferSize);
// Add the secon string
strncat(buffer, secondText, bufferSize-strlen(buffer));
// Output the string
printf("Result: %s\n", buffer);
return 0;
}
我建议,如果可能的话,你应该使用C ++字符串。它们会自动管理内存,从而防止许多与C字符串相关的内存问题。
答案 3 :(得分:1)
这一行
char* cambia[] = {"ciao "};
在动态创建的内存部分中创建名为cambia
的变量,称为“堆栈”。变量是一个没有声明大小的数组,该数组的元素是指向字符的指针。
数组的大小来自初始化程序
{"ciao "}
表示数组只有一个元素,并且该元素使用指向字符串"ciao "
的第一个字符的值进行初始化。但是,字符串"ciao "
放置在一些完全不同的内存区域中 - 它位于静态块中,由编译器使用程序代码中的值进行初始化。编译器不知道你如何使用这些值,特别是它不知道你会用strcat
扩展它,所以它不会在字符串之后保留任何额外的空格。
因此,当您将"mondo"
连接到"ciao "
时,会覆盖内存中的某些数据,可能是一些重要的数据......
我建议您为字符串声明 local 变量,并使用显式大小:
char cambia[ 20] = "ciao ";
char c[] = "mondo";
这将使cambia
变量足够长以保持19个字符的字符串(加上隐式终止零字节'\ 0',ASCII NUL)并用字母'c','i'初始化其前6个字节,'a','o',空格''和NUL。变量c
的隐式大小为6(初始化字符串长度5加1以终止NUL)。
然后你可以安全地连接
strcat( cambia, c);
获取11个字符的字符串“ciao mondo”并将其打印出来
cout <<"cambia: "<<cambia<<endl;
答案 4 :(得分:0)
首先,您不需要标题
#include <string>
#include <cstdlib>
因为没有使用它们的声明。
Aslo标题
#include <string.h>
应该替代
#include <cstring>
在这些陈述中
char* cambia[] = {"ciao "};
char* c[] = {"mondo"};
你定义了两个数组,每个数组都有一个const char *
类型的元素。编译器应发出错误或警告,因为这些定义不正确。按以下方式定义数组是正确的
const char* cambia[] = {"ciao "};
const char* c[] = {"mondo"};
这两个语句定义了指向字符串文字的const指针数组。如果尝试更改程序中的字符串文字,则它是未定义的行为。允许程序将字符串文字放在只读内存中。
你说得对,主要问题在于陈述
strcat( *cambia, *c );
函数strcat
将一个字符数组附加到另一个字符数组的末尾。因此第二个cjaracter数组必须保留足够的内存以容纳附加的字符数组。如果你甚至将数组正确的cambia定义为
char cambia[] = {"ciao "};
它没有足够的内存来存储数组c的字符。
因此,在使用strcat
之前,您需要为连接结果数组放置足够的内存。
您可以通过以下方式执行此操作
char s[11];
strcpy( s, *cambia );
strcat( s, c );
cout << "s: " << s << endl;
考虑到您可以使用标准类std::string
在这种情况下,将一个字符串附加到另一个字符串非常简单。例如
std::string cambia = "ciao ";
std::string c = "mondo";
cambia += c;
或者
cambia.append( c );