Viết chương trình đổi những ký tự đầu tiên của mỗi từ thành chữ in hoa

Đề bài là: Viết chương trình đổi những ký tự đầu tiên của mỗi từ thành chữ in hoa. Em có search google được cái hàm và chạy như dưới đây thì đúng.

#include<iostream>
#include<string>
using namespace std;
#define MAX 50
void toUp(char*);

int main()
{
	char a[MAX];
	cout << "Nhap chuoi a" << endl;
	cin.getline(a, MAX);
	toUp(a);
	cout << a << endl;
	system("pause");
}

void toUp(char *a)
{
	a[0] = toupper(a[0]);
	while (strstr(a, " ") != NULL)
	{
		a = strstr(a, " ") + 1;
		a[0] = toupper(a[0]);
	}
}

Còn khi như này thì báo lỗi ngay dòng a = strstr(a, " ") + 1;

#include<iostream>
#include<string>
using namespace std;
#define MAX 50

int main()
{
	char a[MAX];
	cout << "Nhap chuoi a" << endl;
	cin.getline(a, MAX);
	while (strstr(a, " ") != NULL)
	{
		a = strstr(a, " ") + 1;
		a[0] = toupper(a[0]);
	}
	cout << a << endl;
	system("pause");
}

Các anh giải thích giúp em với, em mới bắt đầu nhập môn C/C++ trên trường thôi, mấy vấn đề liên quan tới con trỏ em chưa nắm chắc lắm. :grinning:

Hàm strstr nằm trong thư viện string.h, và bạn chưa include thư viện này vào --> báo lỗi. Trong C++ dùng lệnh #include <cstring> để đưa thư viện string.h vào.
Còn thư viện #include <string> là lớp string của C++, nó không có hàm strstr.

1 Like

Em đã sửa ctring hay string.h nhưng vẫn báo lỗi ở dòng đó :cry:

array type ‘char [50]’ is not assignable
expression must be a modifiable lvalue

Bạn nhìn kĩ kiểu dữ liệu chỗ hàm ToUp là char *a
Còn ở hàm int của bạn nó khác nhau. Nên lỗi

Không khác đâu bạn, thực ra mảng cũng là một loại con trỏ.
Lúc mình mới bắt đầu học còn mù mờ nên mang lên đây hỏi :smiley:

Tới bh mình vẫn k hiểu đc con trỏ :((. Bạn học khoa nào đấy

2 posts were merged into an existing topic: Topic này chứa các post được cho là Off-topic

Lỗi phát sinh là do bạn đang cố gắng thay đổi giá trị ô nhớ mà tên mảng (biến a) đang trỏ tới tại dòng: a = strstr(a, " ") + 1;

Trong C/C++, tên mảng tuy cũng là một biến chứa địa chỉ ô nhớ giống như biến con trỏ (vì lý do này nên mọi người thường mặc định coi mảng là con trỏ), nhưng tên mảng khác biến con trỏ về bản chất, cụ thể như sau:

  • Biến con trỏ: trong quá trình thực thi chương trình, có thể tùy ý thay đổi giá trị của nó (tức về cơ bản là có thể tùy ý cho con trỏ chỉ tới ô nhớ nào cũng được).
  • Tên mảng: chỉ được chứa địa chỉ ô nhớ mà chương trình cấp phát cho nó vào lúc khởi chạy, và giá trị này không thể thay đổi trong suốt quá trình thực thi chương trình. Lý do cụ thể vì sao người thiết kế ngôn ngữ C không cho tự ý thay đổi giá trị của biến tên mảng là bởi nếu biến tên mảng có thể dễ dàng thay đổi trong quá trình thực thi chương trình thì đó sẽ là một thảm họa trong việc quản lý bộ nhớ. Ví dụ giả sử bạn muốn khởi tạo một mảng char A gồm 10 phần tử, thì về cơ bản trình quản lý sẽ tìm 10 ô nhớ còn trống liền nhau, gán địa chỉ ô nhớ đầu tiên trong dãy này cho biến A và ghi nhớ thêm thông tin là theo sau địa chỉ A này còn 9 ô nữa (vào đâu đó trong bộ nhớ). Nếu trong quá trình thực thi, A có thể tùy ý thay đổi thì sau khi A thay đổi, trình quản lý không thể biết được lúc đầu A chỉ tới vị trí nào, điều này dẫn đến việc giải phóng những ô nhớ mà A đã trỏ tới trước đó (sau khi chương trình kết thúc) là bất khả thi.

Để chương trình thứ 2 của bạn có thể chạy được, thì bạn phải sử dụng một biến con trỏ trung gian, và thao tác trên đó. Bạn có thể sửa lại như sau:

#include<iostream>
#include<string>
using namespace std;
#define MAX 50

int main()
{
    char a[MAX];
    char *p;
    
    cout << "Nhap chuoi a" << endl;
    cin.getline(a, MAX);
    
    p = a;
    while (strstr(p, " ") != NULL)
    {
        p = strstr(p, " ") + 1;
        p[0] = toupper(p[0]);
    }

    cout << a << endl;
        system("pause");

}
3 Likes

Mình đã giải quyết bài này xong rồi, cũng giống như cách bạn vừa làm :smiley:
Dù sao cũng cảm ơn vì sự nhiệt tình giải thích của bạn, chắc chắn nó sẽ rất có ích với mấy bạn mới học như mình lúc đó.
Buổi tối vui vẻ ạ :smile:

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