sách gpt4 ăn đã đi

C++ tạo mã ví dụ chuỗi tiêu chuẩn được định dạng

In lại Tác giả: qq735679552 Thời gian cập nhật: 29-09-2022 22:32:09 25 4
mua khóa gpt4 giày nike

CFSDN nhấn mạnh vào giá trị tạo ra nguồn mở và chúng tôi cam kết xây dựng nền tảng chia sẻ tài nguyên để mọi nhân viên CNTT có thể tìm thấy thế giới tuyệt vời của bạn tại đây.

Bài viết blog CFSDN này C++ tạo mã ví dụ chuỗi tiêu chuẩn được định dạng được tác giả sưu tầm và biên soạn. Nếu bạn quan tâm đến bài viết này, hãy nhớ thích nó.

Hai phương pháp định dạng chuỗi.

Như chúng ta đã biết, std::string của C++ có các chức năng chưa hoàn chỉnh và không có nhiều chức năng khác nhau, chẳng hạn như các hàm định dạng chuỗi.

Trong python3, hai phương thức định dạng chuỗi được hỗ trợ, một là kiểu C, phần định dạng bắt đầu bằng % và % sau tương ứng với loại cụ thể (ví dụ: %s tương ứng với chuỗi %d tương ứng với số nguyên), và cái còn lại Kiểu đầu tiên là kiểu không phụ thuộc vào loại, {0} tương ứng với tham số đầu tiên và {1} tương ứng với tham số thứ hai.

?
1
2
3
4
>>> "Tuổi của {0} là {1}" .định dạng( "đỏ thẫm" , 11)
"Chihong tuổi là 11"
>>> "Tuổi của %s là %d" % ( "đỏ thẫm" , 11)
"Chihong tuổi là 11"

Trong C++, bạn chỉ có thể mượn các hàm C và sử dụng snprintf để định dạng bộ đệm.

?
1
2
3
#define KÍCH THƯỚC BUFFS 512
  char buf[KÍCH THƯỚC BUFFS];
  snprintf(buf, KÍCH THƯỚC BUFFS, "Tuổi của %s là %d\n" , "đỏ thẫm" , 11);

Hoặc sử dụng toán tử luồng độc lập với loại.

?
1
2
3
std::ostringstream os;
trục << "đỏ thẫm" << "Tuổi của là " << 11 << "\N" ;
std::string s = os.str();

Tạm thời đặt vấn đề về hiệu quả sang một bên, phương pháp sử dụng << này để ghép nhiều đối tượng thuộc các loại khác nhau đòi hỏi một lượng lớn mã và việc kiểm soát định dạng đầu ra cụ thể sẽ rắc rối hơn, chẳng hạn như kiểm soát số chữ số bị chiếm dụng bằng một số hoặc số chữ số thập phân. Ít nhất thì nó phức tạp đến mức tôi không thể luôn nhớ nó. Tôi muốn sử dụng snprintf kiểu C để kiểm soát nó. Ví dụ.

?
1
2
gấp đôi d = 3,1415926;
snprintf(buf, KÍCH THƯỚC BUFFS, "Pi: %-8.3lf được Zu Chongzhi phát hiện\n" , d);
?
1
2
$ ./a.ra
Pi: 3.142 được phát hiện bởi Zu Chongzhi

Sử dụng %-8.3lf để đặt số dấu phẩy động loại lf (dài hoặc gấp đôi) thành 8, đặt số chữ số sau dấu thập phân thành 3 và dấu âm có nghĩa là căn lề trái. .

Về việc triển khai bằng tệp tiêu đề iomanip của C++, tôi cũng dành chút thời gian kiểm tra tài liệu.

?
1
2
3
4
gấp đôi d = 3,1415926;
trục << "Pi:" << std::setw(8) << std::fixed
  << std::setprecision(3) << std::left
  << ngày << "Nó được phát hiện bởi Zu Chongzhi\n" ;

Ngoài việc mã quá dài và có khả năng thiếu std::fixed, vấn đề là setprecision đã thay đổi cài đặt mặc định, nghĩa là nếu os << chuyển vào số dấu phẩy động thì số dấu thập phân được giữ lại là vẫn là 3 Bit.

Một số người có thể nói rằng ưu điểm là setprecision và setw có thể nhận một biến thay vì một hằng số. Thực tế, snprintf cũng có thể làm được điều tương tự.

?
1
2
3
gấp đôi d = 3,1415926;
số nguyên n1 = 8, n2 = 3;
snprintf(buf, KÍCH THƯỚC BUFFS, "Pi: %-*.*lf được Zu Chongzhi phát hiện\n" , n1, n2, d);

Trình bao bọc C++ snprintf tạo ra các đối tượng chuỗi std::được định dạng.

Trong APUE UNP TLPI, một số cuốn sách về lập trình C trên Linux, tất cả đều viết thư viện xử lý lỗi của riêng mình để bọc snprintf nhằm tạo ra đầu ra được định dạng, nhằm tránh việc xác định nhiều lần bộ đệm/gọi snprintf, v.v. mỗi lần.

Một nhược điểm của phương pháp này là độ dài của bộ đệm (mảng ký tự) bị hạn chế. Tất nhiên, nói chung, nếu kích thước bộ đệm được xác định đủ lớn thì việc in một chuỗi được định dạng quá dài là đủ. không tốt bằng việc gọi hàm nhiều lần.

Mặt khác, vì các chức năng này chỉ in thông tin, đặc biệt nếu bạn thường xuyên in thông tin rồi thoát trực tiếp khỏi chương trình. Vì vậy, không có chuỗi lỗi nào sẽ được trả lại. Nếu bạn muốn chuyển thông tin lỗi dưới dạng ngoại lệ lên lớp trên để xử lý trong C++ thì những chức năng này là không đủ. Vì vậy, nó cần phải được sửa đổi một cách đơn giản.

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
nội tuyến std::string định dạng_chuỗi( hằng số char * định dạng, va_list đối số) {
  constexpr kích thước_t oldlen = KHÔNG CÓ BUFF;
  char buffer[oldlen]; //Bộ đệm trên ngăn xếp mặc định
  va_list đối số;
  va_copy(đối số, đối số);
  kích thước_t newlen = vsnprintf(&buffer[0], oldlen, định dạng, đối số) + 1;
  mới++; // Đếm dấu kết thúc '\0'
  nếu như (newlen > oldlen) { // Bộ đệm mặc định không đủ lớn và được phân bổ từ heap
   std::vector< char > newbuffer(newlen);
   vsnprintf(newbuffer.data(), newlen, định dạng, argscopy);
   trở lại newbuffer. dữ liệu();
  }
  trở lại đệm;
}
 
nội tuyến std::string định dạng_chuỗi( hằng số char * định dạng, ...) {
  va_list các đối số;
  va_start (đối số, định dạng);
  tự động s = chuỗi định dạng(định dạng, đối số);
  đi_kết thúc (đối số);
 
  trở lại S;
}

Đây là một triển khai bắt chước UNP. Các tham số chính thức được xác định là hai phiên bản của va_list và.... Phiên bản chấp nhận va_list cũng có thể được sử dụng bởi các chức năng khác. Bởi vì danh sách đối số biến đổi kiểu C...không thể được chuyển làm đối số. Một điểm nữa là kiểu va_list không nhất thiết phải có hàm khởi tạo sao chép nên bạn phải sử dụng va_copy để sao chép một va_list cho lần sử dụng thứ hai.

C++ 11 bổ sung thêm tính năng tham số mẫu biến mới, cho phép đơn giản hóa đoạn mã trên.

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
bản mẫu < tên kiểu chữ ...Đối số>
nội tuyến std::string định dạng_chuỗi( hằng số char * định dạng, Args... args) {
   constexpr kích thước_t oldlen = KHÔNG CÓ BUFF;
   char buffer[oldlen]; //Bộ đệm trên ngăn xếp mặc định
 
   kích thước_t newlen = snprintf(&buffer[0], oldlen, định dạng, đối số...);
   mới++; // Đếm dấu kết thúc '\0'
 
   nếu như (newlen > oldlen) { // Bộ đệm mặc định không đủ lớn và được phân bổ từ heap
     std::vector< char > newbuffer(newlen);
     snprintf(newbuffer.data(), newlen, định dạng, đối số...);
     trở lại std::string(newbuffer. dữ liệu());
   }
 
   trở lại đệm;
}

Việc chuyển các tham số mẫu biến đổi cũng rất dễ dàng (sử dụng chuyển tiếp để chuyển tiếp hoàn hảo).

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
xyz@ubuntu:~/unp_practice/lib$ kiểm tra cat.cc
#include
#include
#include "format_string.h"
 
bản mẫu < tên kiểu chữ ...Đối số>
vô hiệu errExit( hằng số char * định dạng, Args... args) {
   tự động errmsg = chuỗi định dạng(định dạng, std::forward(args)...);
   errmsg = errmsg + ": " + lỗi liên tục ( lỗi ) + "\N" ;
   đầu ra (errmsg.c_str(), lỗi chuẩn);
   ra (1);
}
 
số nguyên chủ yếu() {
   hằng số char * s = "Xin chào thế giới!" ;
   số nguyên fd = -1;
   nếu như (viết(fd, s, căng thẳng (c)) == -1)
     errExit( "ghi \"%s\" vào tệp mô tả(%d) không thành công" , s, fd);
   trở lại 0;
}
xyz@ubuntu:~/unp_practice/lib$ g++ test.cc -std=c++11
xyz@ubuntu:~/unp_practice/lib$ ./a.out
viết "Xin chào thế giới!" đến file descriptor(-1) không thành công: Mô tả file không hợp lệ

Tóm tắt.

Trên đây là toàn bộ nội dung bài viết mong rằng nội dung bài viết có giá trị tham khảo nhất định cho quá trình học tập, làm việc của mọi người.

Link gốc: https://www.jianshu.com/p/548e43f4ced8.

Cuối cùng, bài viết này về việc tạo mã ví dụ chuỗi tiêu chuẩn được định dạng bằng C++ kết thúc ở đây. Nếu bạn muốn biết thêm về mã ví dụ chuỗi tiêu chuẩn được định dạng bằng C++, vui lòng tìm kiếm các bài viết CFSDN hoặc tiếp tục duyệt các bài viết liên quan, tôi hy vọng bạn sẽ ủng hộ blog của tôi trong phần này. tương lai! .

25 4 0
qq735679552
Hồ sơ

Tôi là một lập trình viên xuất sắc, rất giỏi!

Nhận phiếu giảm giá taxi Didi miễn phí
Phiếu giảm giá taxi Didi
Chứng chỉ ICP Bắc Kinh số 000000
Hợp tác quảng cáo: 1813099741@qq.com 6ren.com
Xem sitemap của VNExpress