cách tạo điểm ngắt có điều kiện với std :: string


81

Giả sử tôi có chức năng này:

std::string Func1(std::string myString)
{
   //do some string processing 
   std::string newString = Func2(myString)
   return newString;  
}

làm cách nào để đặt ngắt newStringcó điều kiện khi có giá trị cụ thể? (không cần thay đổi nguồn)

thiết lập một điều kiện newString == "my value"

không hoạt động các điểm ngắt bị vô hiệu hóa với lỗi "không tìm thấy toán tử quá tải"


1
Tôi không biết đây có phải là chủ ý không, nhưng mã của bạn bị hỏng. Func1 trả về void, nhưng bạn trả về một chuỗi std ::. Func2 không được hiển thị, nhưng nó có thể không trả về chuỗi std ::, hơn nữa bạn đang sử dụng toán tử == (bằng) thay vì = (gán).
falstro

Ví dụ xấu đứng về phía tôi, cố định nhưng điểm là để minh họa cho vấn đề nhận được một breakpoint có điều kiện với std :: string để làm việc
Eli

Câu trả lời:


49

Một số tìm kiếm không tìm thấy bất kỳ cách nào để thực hiện việc này. Các lựa chọn thay thế được đề xuất là đưa thử nghiệm vào mã của bạn và thêm một điểm ngắt tiêu chuẩn:

if (myStr == "xyz")
{
    // Set breakpoint here
}

Hoặc để xây dựng bài kiểm tra của bạn từ việc so sánh các ký tự riêng lẻ. Ngay cả khi nhìn vào các ký tự riêng lẻ trong chuỗi cũng hơi khó xử; trong Visual Studio 2005, tôi phải đi sâu vào các biến thành viên như

myStr._Bx._Buf[0] == 'x' && myStr._Bx._Buf[1] == 'y' && myStr._Bx._Buf[2] == 'z'

Cả hai cách tiếp cận này đều không khả quan. Chúng ta nên có quyền truy cập tốt hơn vào một tính năng phổ biến của Thư viện Chuẩn.


+1. Tôi chỉ đang viết một câu trả lời tương tự. Cách duy nhất tôi biết để làm điều này là nhìn vào bên trong quá trình thực hiện. Lưu ý rằng đối với std :: string, điều này có thể khá phức tạp vì tối ưu hoá chuỗi ngắn.
Adrian McCarthy

Điều này có vấn đề myStr._Bx._Buflà chỉ có giá trị khi myStr._Mysize < _BUF_SIZE. Nếu không, bạn cần sử dụngmyStr._Bx._Ptr
RunHolt

3
Câu trả lời này không còn phù hợp với Visual Studio mới hơn. strcmp(myStr._Mypair._Myval2._Bx._Ptr, "xyz") == 0chỉ hoạt động
Michael Veksler

85

Có một cách dễ dàng hơn nhiều trong Visual Studio 2010/2012.

Để thực hiện những gì bạn đang tìm kiếm trong ANSI, hãy sử dụng cái này:

strcmp(newString._Bx._Ptr,"my value")==0 

Và trong unicode (nếu newString là unicode) sử dụng điều này:

wcscmp(newString._Bx._Ptr, L"my value")==0 

Có nhiều điều bạn có thể làm hơn là chỉ so sánh, bạn có thể đọc thêm về nó tại đây:

http://blogs.msdn.com/b/habibh/archive/2009/07/07/new-visual-studio-debugger-2010-feature-for-cc-developers-using-string-functions-in-conditional- breakpoints.aspx


Tôi thích câu trả lời này, nó đã làm việc cho tôi (với một số ngoại lệ mà bộ nhớ không thể truy cập được).
tuốt

23
Như các nhận xét khác đã đề xuất, việc truy cập newString._Bx._Ptrcó thể không hoạt động đối với các chuỗi ngắn. Trong trường hợp của tôi, tôi nhận được "Đã cố đọc hoặc ghi bộ nhớ được bảo vệ". Đối với các chuỗi ngắn (16 ký tự trở xuống?), newString._Bx._BufDường như giữ các ký tự.
vvnurmi

1
Điều này cũng sẽ hoạt động trong VS2015? Bởi vì nó dường như không làm việc trên kết thúc của tôi ...
BmyGuest

1
Tôi không biết về VS, nhưng đối với gdb, bạn có thể viết strcmp(newString.c_str(), "my_value") == 0. Có thể cần nhiều phân tích tính toán hơn, nhưng dễ nhớ hơn.
Jounathaen

1
@Jounathaen Rất tiếc không hoạt động trong VS: "Biểu hiện này có tác dụng phụ và sẽ không được đánh giá."
letmaik

19

Trong VS2017, bạn có thể làm

strcmp(newString._Mypair._Myval2._Bx._Buf,"myvalue")==0

3
Nó thực sự phụ thuộc vào Windows SDK bạn đang sử dụng. Tôi đang sử dụng 10.1.15068 với Visual Studio 2015 và điều này hoạt động, trong khi string._Bx._Buf hoặc string._Bx._Ptr thì không.
Stuart Welch

13

Trong VS2017, tôi có thể đặt điều kiện là:

strcmp(&newString[0], "my value") == 0

Cũng hoạt động trong VS2019 và rõ ràng hơn, dễ đọc và dễ nhớ hơn tất cả các câu trả lời khác.
Scott Hutchinson

8

Mặc dù tôi đã phải giải quyết vấn đề này bằng cách sử dụng thứ gì đó tương tự như câu trả lời của Brad (cộng với việc sử dụng DebugBreak () để ngắt ngay khỏi mã), đôi khi việc chỉnh sửa / biên dịch lại / chạy lại một chút mã là quá tốn thời gian hoặc đơn giản là không thể .

May mắn thay, rõ ràng là có thể spelunk vào các thành viên thực tế của lớp std :: string. Một cách được đề cập ở đây - và mặc dù anh ấy gọi cụ thể là VS2010, bạn vẫn có thể truy cập các ký tự riêng lẻ theo cách thủ công trong các phiên bản trước đó. Vì vậy, nếu bạn đang sử dụng 2010, bạn chỉ có thể sử dụng các strcmp()chức năng tốt và tương tự ( thông tin thêm) , nhưng nếu bạn giống tôi và vẫn sử dụng năm 2008 hoặc trước đó, bạn có thể tìm ra một giải pháp thay thế tồi tàn, khủng khiếp nhưng đầy đủ chức năng bằng cách đặt điều kiện cho điểm ngắt như:

strVar._Bx._Ptr[0] == 'a' && strVar._Bx._Ptr[1] == 'b' &&
   strVar._Bx._Ptr[2] == 'c'

để ngắt nếu ba ký tự đầu tiên trong strVar là "abc". Tất nhiên, bạn có thể tiếp tục với các ký tự bổ sung. Xấu xí .. nhưng nó đã tiết kiệm cho tôi một chút thời gian vừa rồi.



3

@OBWANDO (gần như) có giải pháp , nhưng như nhiều nhận xét đã chỉ ra đúng, bộ đệm thực tế phụ thuộc vào kích thước chuỗi; Tôi thấy 16 là ngưỡng. Trước khi kiểm tra kích thước cho strcmp trên bộ đệm thích hợp hoạt động.

newString._Mysize < 16 && strcmp(newString._Bx._Buf, "test value") == 0

hoặc là

newString._Mysize >= 16 && strcmp(newString._Bx._Ptr, "ultra super long test value") == 0

Đây là hệ quả của việc tối ưu hóa bộ đệm nhỏ. Tổng quan cấp cao tại đây blog.msmvps.com/gdicanio/2016/11/17/… . Tìm hiểu sâu hơn ở đây akrzemi1.wordpress.com/2014/04/14/common-optimizations
Aerom Xundes

2

Đã cố gắng sử dụng strcmptrong gdb8.1under ubuntu18.04, nhưng nó không hoạt động:

(ins)(gdb) p strcmp("a", "b")
$20 = (int (*)(const char *, const char *)) 0x7ffff5179d60 <__strcmp_ssse3>

Theo đó câu trả lời , strcmplà một đặc biệt IFUNC , một điều kiện thiết lập có thể như thế này:

condition 1 __strcmp_ssse3(camera->_name.c_str(), "ping")==0

Nó khá xấu xí, không muốn làm lần thứ hai.

Câu trả lời này cung cấp một giải pháp tốt hơn nhiều, nó sử dụng std :: string :: so sánh :

condition 1 camera->_name.compare("ping") == 0


1

So sánh chuỗi hoạt động tốt hơn so với các ký tự

strcmp(name._Mypair._Myval2._Bx._Buf, "foo")==0

Điều này hoạt động, nhưng rất bất tiện khi sử dụng và dễ xảy ra lỗi.

name._Mypair._Myval2._Bx._Buf[0] == 'f' && 
name._Mypair._Myval2._Bx._Buf[1] == '0' && 
name._Mypair._Myval2._Bx._Buf[2] == '0'

1

Bạn có thể chuyển nó thành chuỗi ac bằng cách sử dụng c_str()như sau:

$_streq(myStr.c_str(), "foo")

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.