30/09/2018, 18:53

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 ạ
    tks em xin chân thành cảm ơn
明玉 viết 21:09 ngày 30/09/2018

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;
Vu Nguyentuan viết 20:58 ngày 30/09/2018

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

明玉 viết 20:54 ngày 30/09/2018

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.

Vu Nguyentuan viết 20:54 ngày 30/09/2018

à 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ỉ

Vu Nguyentuan viết 20:58 ngày 30/09/2018

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
Vu Nguyentuan viết 21:00 ngày 30/09/2018

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

Đạt Đỗ viết 20:56 ngày 30/09/2018

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

明玉 viết 21:01 ngày 30/09/2018

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.

Vu Nguyentuan viết 21:02 ngày 30/09/2018

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 ^^!

Vu Nguyentuan viết 21:05 ngày 30/09/2018

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

Vu Nguyentuan viết 20:54 ngày 30/09/2018

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 ạ

明玉 viết 20:59 ngày 30/09/2018

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 đó.

Vu Nguyentuan viết 20:58 ngày 30/09/2018

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…

明玉 viết 21:01 ngày 30/09/2018

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.

Vu Nguyentuan viết 21:07 ngày 30/09/2018

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]

Vu Nguyentuan viết 20:59 ngày 30/09/2018

đâ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();
}
明玉 viết 21:00 ngày 30/09/2018

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.

Vu Nguyentuan viết 21:00 ngày 30/09/2018

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);

Vu Nguyentuan viết 21:03 ngày 30/09/2018

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

Nguyễn Kim Nam viết 20:56 ngày 30/09/2018

Các bro cho e hỏi vẫn như vậy mà trong c thì em nên làm thế nào ạ? e thử nhiều cái mà không thể ra đúng số như vậy ạ. ai biết chỉ giúp em với. Thanks ạ

Bài liên quan
0