Làm cách nào để phân chia một chuỗi ký tự theo nhiều dòng trong C / Objective-C?


321

Tôi có một truy vấn sqlite khá dài:

const char *sql_query = "SELECT statuses.word_id FROM lang1_words, statuses WHERE statuses.word_id = lang1_words.word_id ORDER BY lang1_words.word ASC";

Làm thế nào tôi có thể ngắt nó trong một số dòng để dễ đọc hơn? Nếu tôi làm như sau:

const char *sql_query = "SELECT word_id
                        FROM table1, table2
                        WHERE table2.word_id = table1.word_id
                        ORDER BY table1.word ASC";

Tôi đang nhận được một lỗi.

Có cách nào để viết truy vấn trong nhiều dòng không?

Câu trả lời:


569

Có hai cách để phân chia chuỗi trên nhiều dòng:

Sử dụng \

Tất cả các dòng trong C có thể được chia thành nhiều dòng bằng \.

Đồng bằng C:

char *my_string = "Line 1 \
                   Line 2";

Mục tiêu-C:

NSString *my_string = @"Line1 \
                        Line2";

Cách tiếp cận tốt hơn

Có một cách tiếp cận tốt hơn chỉ hoạt động cho chuỗi.

Đồng bằng C:

char *my_string = "Line 1 "
                  "Line 2";

Mục tiêu-C:

NSString *my_string = @"Line1 "
                       "Line2";    // the second @ is optional

Cách tiếp cận thứ hai tốt hơn, vì không có nhiều khoảng trắng bao gồm. Đối với một truy vấn SQL, tuy nhiên, cả hai đều có thể.

LƯU Ý: Với #define, bạn phải thêm một '\' để nối hai chuỗi:

Đồng bằng C:

#define kMyString "Line 1"\
                  "Line 2"

22
Cả hai đều giống như trong và C và C ++. Giải pháp thứ hai được ưa thích vì giải pháp trước đây nhúng rất nhiều khoảng trắng vô dụng vào chương trình cũng sẽ được truyền đến máy chủ DB.
Alnitak

Bạn đang thiếu một @ ở đầu dòng 2 trong ví dụ Objective-C tốt hơn.
Lawrence Johnston

Bạn có một liên kết đến một thông số kỹ thuật tài liệu tùy chọn của thứ hai @?
Heath B ranh giới

@HeathBnings: Không phải ở đây, nhưng tôi đã tra cứu nó khi tôi viết câu trả lời.
Georg Schölly

10
Một ưu điểm khác của cách tiếp cận tốt hơn là bạn có thể đặt // bình luận sau mỗi dòng.

110

Có một mẹo bạn có thể làm với bộ xử lý trước.
Nó có tiềm năng xuống phía dưới là nó sẽ thu gọn khoảng trắng và có thể gây nhầm lẫn cho những người đọc mã.
Tuy nhiên, mặt trái của nó là bạn không cần phải thoát các ký tự trích dẫn bên trong nó.

#define QUOTE(...) #__VA_ARGS__
const char *sql_query = QUOTE(
    SELECT word_id
    FROM table1, table2
    WHERE table2.word_id = table1.word_id
    ORDER BY table1.word ASC
);

bộ tiền xử lý biến điều này thành:

const char *sql_query = "SELECT word_id FROM table1, table2 WHERE table2.word_id = table1.word_id ORDER BY table1.word ASC";

Tôi đã sử dụng thủ thuật này khi tôi đang viết một số bài kiểm tra đơn vị có chuỗi ký tự lớn chứa JSON. Điều đó có nghĩa là tôi đã không phải thoát khỏi mọi ký tự trích dẫn \ ".


5
Hoàn hảo! Bây giờ tôi chỉ cần cung cấp thêm vài trăm upvote này và lấy nó ở nơi nó thuộc về ...
Mike

Tôi đã phản ứng theo cách tương tự, nhưng điều này không phải là không có vấn đề. Tôi vừa thử thực hiện một cách di truyền theo cách này với một ký tự Unicode đặc biệt và đã gặp lỗi về các ký tự không phải ASCII không được phép bên ngoài chữ.
philipkd

+1 nhưng đối với bản ghi tôi có vấn đề với trình biên dịch (MSVC) hoặc trình soạn thảo (QtCreator) không (biên dịch lại) biểu thức khi cần thay đổi. Nó giống như thay đổi không được phát hiện ... Đánh Rebuild thay vì Build thực hiện thủ thuật.
Andreas

Cảm ơn bạn cho gà Nugget thông tin này. Nó thực hiện chính xác những gì tôi cần làm mà không cần thêm rác.
FishGuy876

Thật không may, nó không hoạt động nếu bạn có dấu ngoặc kép trong chuỗi. Vâng, nó là loại công việc, trong đó nó tạo ra một cảnh báo. Nhưng cơ sở mã của tôi là
-Werror

24

Bạn cũng có thể truy cập XCode -> Tùy chọn, chọn tab thụt lề và bật Gói kết thúc.

Bằng cách đó, bạn sẽ không phải nhập thêm bất cứ điều gì và nó sẽ hoạt động cho những thứ bạn đã viết. :-)

Một điều khó chịu là ...

if (you're long on indentation
    && short on windows) {
            then your code will
                end up squished
                     against th
                         e side
                             li
                              k
                              e

                              t
                              h
                              i
                              s
}

2
@YoYoYonnY Tôi đồng ý, nhưng tôi cũng đánh giá cao nó. Tôi nhận ra rằng bình luận này sẽ không thực sự có thể là một bình luận, do đó việc sử dụng định dạng câu trả lời. Điều này có vẻ như là một hạn chế của S / O, rằng bạn không thể viết bình luận đặc biệt phong phú (theo như tôi biết).
Max von Hippel

24

Tôi luôn gặp phải vấn đề này, vì vậy tôi đã tạo ra một công cụ nhỏ để chuyển đổi văn bản thành chuỗi Objective-C đa dòng thoát:

http://multilineobjc.herokuapp.com /

Hy vọng điều này sẽ giúp bạn tiết kiệm thời gian.


1
công cụ tuyệt vời! câu hỏi: tại sao bạn thoát '|'?
justadreamer

Điểm tốt. Tôi đã thay đổi nó để không còn thoát "|". Cảm ơn vì đã cho tôi biết.
Flaviu

Tôi đã có cùng một ý tưởng. Ước gì tôi sẽ thấy điều này đầu tiên. Công cụ của tôi là: nsopesify.nateflink.com
Nate Flink

1
Cảm ơn, đã tiết kiệm cho tôi rất nhiều thời gian!
djskinner

Hãy thử sử dụng Định dạng Clang (tích hợp với các biên tập viên yêu thích của bạn): clang.llvm.org/docs/ClangFormat.html
Ahmed Fasih

18

Mở rộng ý tưởng Trích dẫn cho Mục tiêu-C:

#define NSStringMultiline(...) [[NSString alloc] initWithCString:#__VA_ARGS__ encoding:NSUTF8StringEncoding]

NSString *sql = NSStringMultiline(
    SELECT name, age
    FROM users
    WHERE loggedin = true
);

3
#define NSStringMultiline(...) @#__VA_ARGS__nên làm việc quá.
Nicholas Daley

Đối với dây có thể thay đổi: #define NSStringMultiline(...) [[NSMutableString alloc] initWithCString:#__VA_ARGS__ encoding:NSUTF8StringEncoding]
Rimsky

Đối với tôi, chuỗi kết quả không có dòng mới.
Rimsky

Dòng mới thoát được nắm bắt chính xác (điều này gần như không thuận tiện hoặc tốt đẹp).
rimsky

@rimsky, Và tôi nghĩ rằng nó #define NSStringMultiline(...) [@#__VA_ARGS__ mutableCopy]cũng hoạt động cho các chuỗi có thể thay đổi.
Iulian Onofrei

5

Thêm một giải pháp nữa cho cọc, thay đổi tệp .m của bạn thành .mm để nó trở thành Objective-C ++ và sử dụng chữ thô C ++, như thế này:

const char *sql_query = R"(SELECT word_id
                           FROM table1, table2
                           WHERE table2.word_id = table1.word_id
                           ORDER BY table1.word ASC)";

Chữ thô bỏ qua tất cả mọi thứ cho đến khi chuỗi kết thúc, trong trường hợp mặc định là dấu ngoặc đơn.

Nếu chuỗi trích dẫn dấu ngoặc đơn phải xuất hiện trong chuỗi ở đâu đó, bạn cũng có thể dễ dàng chỉ định một dấu phân cách tùy chỉnh, như sau:

const char *sql_query = R"T3RM!N8(
                                  SELECT word_id
                                  FROM table1, table2
                                  WHERE table2.word_id = table1.word_id
                                  ORDER BY table1.word ASC
                         )T3RM!N8";

Tôi cũng phát hiện ra rằng GCC thêm C ++ xâu liệu như một mở rộng của ngôn ngữ C: stackoverflow.com/questions/797318/...
Ciro Santilli郝海东冠状病六四事件法轮功

3

Bạn cũng có thể làm:

NSString * query = @"SELECT * FROM foo "
                   @"WHERE "
                     @"bar = 42 "
                     @"AND baz = datetime() "
                   @"ORDER BY fizbit ASC";

2

GCC bổ sung thêm chuỗi ký tự thô đa dòng C ++ dưới dạng phần mở rộng C

C ++ 11 có chuỗi ký tự thô như đã đề cập tại: https://stackoverflow.com/a/44337236/895245

Tuy nhiên, GCC cũng thêm chúng dưới dạng tiện ích mở rộng C, bạn chỉ cần sử dụng -std=gnu99thay vì -std=c99. Ví dụ:

C chính

#include <assert.h>
#include <string.h>

int main(void) {
    assert(strcmp(R"(
a
b
)", "\na\nb\n") == 0);
}

Biên dịch và chạy:

gcc -o main -pedantic -std=gnu99 -Wall -Wextra main.c
./main

Điều này có thể được sử dụng ví dụ để chèn lắp ráp nội tuyến đa dòng vào mã C: Làm thế nào để viết mã lắp ráp nội tuyến đa dòng trong GCC C ++?

Bây giờ bạn chỉ cần nằm lại và chờ đợi nó được chuẩn hóa trên C20XY.

C ++ đã được hỏi tại: C ++ multiline chuỗi bằng chữ

Đã thử nghiệm trên Ubuntu 16.04, GCC 6.4.0, binutils 2.26.1.


0

Một cách khác là sử dụng bất kỳ công cụ nào để loại bỏ ngắt dòng. Viết chuỗi của bạn bằng bất kỳ trình soạn thảo văn bản nào, sau khi bạn hoàn thành, dán văn bản của bạn vào đây và sao chép lại chuỗi đó trong xcode.


1
Không thực sự là một giải pháp lâu dài. Điều gì nếu bạn phải thay đổi nó một lần nữa sau đó. Nhận được sự khó chịu nhanh chóng, tốt hơn để sử dụng các kỹ thuật đa dòng đã được đề cập và định dạng trực tiếp trong tệp.
Schwarzie2478
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.