Làm sao để nối chuỗi 2 vào chuỗi 1 kiểu char và kiểu string

đầu tiên là kiểu char

  • VD em đang có char s1[5], s2[5]
    gán s1= 12345
    gán s2= 67890
    bây giờ em muốn nối s2 vào s1
    và s1 trờ thành s1=1234567890
    thì phải khắc phục cách khai báo ntn để đc kết quả như trên… kiểu như danh sách liên kết ý k cần biết có bnhiu phần tử cứ dùng bnhiu thì cấp phát bấy nhiêu
    thứ 2 là kiểu string
    string thì k dùng đc cái strcat rồi vậy thì nối ntn ạ :smile:
    tks em xin chân thành cảm ơn

Xử lý nối mấy chuỗi char trong C là cả cực hình đó, có std::string thì làm thế này cho lẹ:

std::string s1;
std::string s2;
std::getline(std::cin, s1);
std::getline(std::cin, s2);
s1 += s2;
std::cout << s1 << endl;
1 Like

+= luôn đc ạ… k cần định nghĩa lại += à

std::string có sẵn mà bạn, nối được cả kiểu char luôn:
http://www.cplusplus.com/reference/string/string/operator+=/
(Dùng std::wstring là lưu được cả Tiếng Việt, phần tử con là wchar_t)
Nếu bạn muốn ghép nhiều string 1 lần luôn (Giống hàm String.Concat của DotNet) thì nên dùng cái này.

2 Likes

à string thì ngon rồi không ngờ nó làm đc kiểu đấy hơn hẳn kiểu char
thế h mình k muốn dùng kiểu string nữa mà muốn dùng kiểu char *a thì k biết có khắc phục đc cái độ dài kia k nhỉ

bác nào thông giúp e câu này cái

  • có phải khai báo char *s; thì sẽ k còn bị giới hạn về độ dài nữa không
    bác nào có thể vd cho e 1 cái code sự dụng char *s; đc không ạ em cảm ơn

String(const String&);
câu lệnh trên nghĩa là gì ạ

char *s là khai báo cho trỏ mà.

1 Like

std::string nó làm được vậy do trong class nó auto hết cho mình rồi, còn dùng char* thì phải tự lo về vấn đề bộ nhớ thôi (trừ khi bạn viết hẳn một class như std::string)

Muốn xài char* mà nhập bất kỳ thì cấp phát động bộ nhớ:

int n1;
std::cout << "Enter max size of s1: ";
std::cin >> n1;
std::cin.ignore(); // dùng để tiêu thụ nốt cái ký tự enter trong bộ đệm
std::cout << "Enter first string: ";
char* s1 = new char[n1];
std::cin.getline(s1, n1); // nếu nhập dài hơn n1 thì phần dài hơn sẽ mất
std::cin.ignore();

int n2;
std::cout << "Enter max size of s2: ";
std::cin >> n2;
std::cin.ignore();
std::cout << "Enter second string: ";
char* s2 = new char[n2];
std::cin.getline(s2, n2);
std::cin.ignore();

int len1 = strlen(s1);
int len2 = strlen(s2);

char* s3 = new char[len1 + len2 + 1]; // tạo ra s3 có độ dài vừa đủ cộng thêm 1 ký tự '\0'
strcpy(s3, s1);
char* s33 = s3 + len1; // dịch chuyển con trỏ s3 ra sau để strcat chạy lẹ hơn
strcat(s33, s2);

std::cout << "Combined string: ";
std::cout << s3;

String(const String&);
câu lệnh trên nghĩa là gì ạ

Bạn học class constructor là hiểu.

2 Likes

thật đúng là quý hơn vàng
mình rất rất cảm ơn… nó đã cứu sống mình ^^!

mà bác đăng code c nên kiểu j mà nó màu mè thế
mình đăng nên nó như chữ viết thông thường

a = new char[3]
câu lệnh trên là có phải cấp cho a 1 vùng nhớ kiểu char có tối đa là 3 kí tự k ạ
tức là khi mình nhập a= 123 vẫn oke đúng k ạ

Không được, trong C++ không có thể loại gán chuỗi char ngon ơ thế đâu (trừ khi bạn overload toán tử), gán chuỗi char tốt nhất cứ dùng strcpy.
Cái đó đúng ra là cấp phát trên vùng nhớ heap 3 byte ứng với 3 phần tử char, còn a là 1 pointer (1 số nguyên 4 byte hoặc 8 byte nếu là 64 bit) có giá trị là địa chỉ bộ nhớ, trỏ vào vùng nhớ heap đó.

mình không đề cập đến vấn đề gán như thế nào
mặc đinh là mình gán đúng đi
nhưng khi mình cấp cho biến a = new char[3]
thì biến a lúc này lưu được tối đa bnhiu kí tự
hay nói cách khác là char a[3] và a = new char[3] cái số 3 nó có giống nhau không
mặc định cho tất cả cái còn lại đều đúng
cảm ơn bác rất nhiều…

Hai cái đó đều lưu được tối đa 3 ký tự như nhau, chỉ có lưu trữ khác nhau thôi.

nhưng mình có đoạn code ntn

	cout<<"Nhap do dai: ";
	cin>>dodai;
	fflush(stdin);
	s = new char[dodai];
	cout<<"nhap chuoi: ";
	cin.get(s,10);

khi mình nhập dodai =3
sau đó nhập tiếp chuỗi 1234567
thì chương trình của mình vẫn in ra 7 kí tự
từ đó mình đoán cái s= new char[size] cái size này không phải là cái size trong char s[size]

đây là code nhé bác sẽ thấy rõ hơn cái kiểu cấp phát new

#include<iostream>
#include <string.h>
#include<stdio.h>
#include <conio.h>
#include <stdlib.h>
using namespace std;
class cstring{
	char *s;
	int dodai;
	public:
		cstring();
		~cstring(){
			delete []s;
			dodai = 0;
		}
		void nhap();
		void xuat();
		friend cstring operator +(const cstring a,const cstring b);
		const cstring& operator=(const cstring &);
		friend cstring operator +=(cstring a, const cstring b);
		char  operator [] (int id)const ;
		void leng();
			
		
};
void cstring::leng()
{
	cout<<"do dai cua a = "<<strlen(s);
	cout<<"dodai="<<dodai;
}
cstring::cstring()
{
	dodai=0;
	s=NULL;
}
void cstring::nhap()
{
	cout<<"Nhap do dai: ";
	cin>>dodai;
	fflush(stdin);
	s = new char[dodai];
	cout<<"nhap chuoi: ";
	cin.get(s,10);
	if(strlen(s)<(dodai))
	{
		char *t;
		t = new char[strlen(s)];
		strcpy(t,s);
		delete[]s;
		s=new char[strlen(s)];
		strcpy(s,t);
		dodai=strlen(s);
	}
	cin.ignore();
}
void cstring::xuat()
{
	cout<<s;
}
const cstring& cstring::operator=(const cstring &a)
{
	dodai=a.dodai;
	delete []s;
	s = new char[dodai];
	strcpy(s,a.s);
	return *this;
}
cstring operator+(const cstring a,const cstring b)// loi o day
{
	cstring tam;
	delete []tam.s; 
	tam.s=new char[a.dodai+b.dodai];
	strcpy(tam.s,a.s);
	strcat(tam.s,b.s);
	return tam;
}
cstring operator +=(cstring a, const cstring b)
{
	cstring tam;
	tam= a+b;
	a=tam;
	return a;
}
char cstring::operator [] (int id)const{
	if (id<0) return s[0];
	if(id>=0) return s[dodai-1];
	return s[id] ;
}

main()
{
	cstring a,b,c;
	int id;
	a.nhap();
	cout<<"a=";
	a.xuat();
	cout<<endl;
	b.nhap();
	cout<<"b=";
	b.xuat();
	cout<<endl;
	a.leng();
	cout<<endl<<"nhap vi tri muon lay o chuoi a:";
	cin>>id;
	cout<<endl<<a[id]<<endl;
	cout<<endl<<"gan c=a"<<endl<<"c=";
	c=a;
	c.xuat();
	cout<<endl;
	cout<<endl<<"a+b=c=";
	c=a+b;// loi o day
	c.xuat();
	cout<<endl;
	a+=b;
	cout<<"a+=b=a=";
	a.xuat();
	getch();
}

Cái size đó là size tối đa mà bạn dùng được an toàn, ra khỏi ngưỡng cấp phát thì gọi là buffer overflow. Code bạn bị buffer overflow rồi.
Bạn đang dùng hàm cin.get(char* s, streamsize n) mà bạn đưa 10 vào làm n. Như vậy hàm này hiểu rằng s có thể nhận tối đa an toàn 10 ký tự, mà thực ra chỉ có được ‘dodai’ ký tự an toàn thôi. Phần “4567” trong chuỗi của bạn đã tràn ra khỏi mảng và lấn sang vùng dữ liệu khác rồi.

1 Like

mình đưa số 10 vào để nhập tối đa đc 10 kí tự để thử cái new char[dodai] thôi. chứ thực chất cái số 10 ý là dodai. cin.get(s,dodai);

mình rất cảm ơn bác… nhờ có bác mà e mới làm đc đoạn code trên
1 lần nữa mình rất cảm ơn

1 Like
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?