Mã C


12

Tình huống: Bạn là một giáo viên trung học, dạy cho lớp máy tính của bạn cách viết chương trình C. Tuy nhiên, vì đây mới chỉ là bắt đầu của thuật ngữ, bạn đã không dạy họ về tầm quan trọng của việc thụt và khoảng cách. Khi bạn đang đánh dấu công việc của họ, đôi mắt của bạn bị tổn thương rất nhiều, bạn hét lên đau đớn và nhận ra rằng điều này không thể tiếp tục.

Nhiệm vụ: Bạn đã quyết định viết một chương trình, bằng bất kỳ ngôn ngữ nào, lấy mã nguồn C hợp lệ làm đầu vào và đầu ra nó được định dạng độc đáo. Bạn nên quyết định đâu là một mã được định dạng độc đáo, vì đó là một cuộc thi phổ biến. Bạn được khuyến khích triển khai càng nhiều tính năng càng tốt, sau đây là một số ví dụ:

  • Thêm thụt lề thích hợp ở phía trước của mỗi dòng
  • Thêm khoảng trắng sau ,và các toán tử khác, ví dụ: chuyển đổi int a[]={1,2,3};sang int a[] = {1, 2, 3};. Hãy nhớ không xử lý các toán tử trong chuỗi ký tự mặc dù.
  • Xóa dấu cách sau mỗi dòng
  • Tách các câu thành nhiều dòng, ví dụ học sinh có thể viết tmp=a;a=b;b=tmp;hoặc int f(int n){if(n==1||n==2)return 1;else return f(n-1)+f(n-2);}tất cả trong một dòng, bạn có thể tách chúng thành các dòng khác nhau. forMặc dù vậy, hãy chú ý đến các vòng lặp, chúng có dấu chấm phẩy trong đó nhưng tôi thực sự không nghĩ bạn nên tách chúng ra.
  • Thêm một dòng mới sau khi xác định từng chức năng
  • Một tính năng khác mà bạn có thể đưa ra với sự giúp đỡ bạn hiểu được mã của học sinh.

Tiêu chí chiến thắng: Đây là một cuộc thi phổ biến, vì vậy câu trả lời với hầu hết các chiến thắng đều thắng. Trong trường hợp hòa, câu trả lời có nhiều tính năng nhất được thực hiện sẽ thắng. Nếu đó là hòa một lần nữa thì mã ngắn nhất sẽ thắng.

Bạn nên đưa vào câu trả lời của mình một danh sách các tính năng mà bạn đã triển khai, cũng như đầu vào và đầu ra mẫu.

Chỉnh sửa: Theo yêu cầu trong các nhận xét ở đây là một đầu vào mẫu, mặc dù hãy nhớ rằng nó chỉ mang tính tham khảo và bạn nên thực hiện càng nhiều tính năng càng tốt.

Đầu vào:

#include <stdio.h>
#include<string.h>
int main() {
int i;
char s[99];
     printf("----------------------\n;;What is your name?;;\n----------------------\n"); //Semicolon added in the string just to annoy you
             /* Now we take the input: */
    scanf("%s",s);
    for(i=0;i<strlen(s);i++){if(s[i]>='a'&&s[i]<='z'){
        s[i]-=('a'-'A'); //this is same as s[i]=s[i]-'a'+'A'
}}printf("Your name in upper case is:\n%s\n",s);
   return 0;}

Đây là cách tôi thường định dạng mã này: (Tôi là một người lười biếng)

#include <stdio.h>
#include <string.h>
int main() {
    int i;
    char s[99];
    printf("----------------------\n;;What is your name?;;\n----------------------\n"); //Semicolon added in the string just to annoy you
    /* Now we take the input: */
    scanf("%s",s);
    for(i=0;i<strlen(s);i++) {
        if(s[i]>='a'&&s[i]<='z') {
            s[i]-=('a'-'A'); //this is same as s[i]=s[i]-'a'+'A'
        }
    }
    printf("Your name in upper case is:\n%s\n",s);
    return 0;
}

Đây là cách tôi nghĩ dễ đọc hơn:

#include <stdio.h>
#include <string.h>
int main() {
    int i;
    char s[99];
    printf("----------------------\n;;What is your name?;;\n----------------------\n"); //Semicolon added in the string just to annoy you
    /* Now we take the input: */
    scanf("%s", s);
    for(i = 0; i < strlen(s); i++) {
        if(s[i] >= 'a' && s[i] <= 'z') {
            s[i] -= ('a' - 'A'); //this is same as s[i]=s[i]-'a'+'A'
        }
    }
    printf("Your name in upper case is:\n%s\n", s);
    return 0;
}




Ngoài ra, bây giờ tôi bắt đầu có câu trả lời, câu trả lời có số phiếu cao nhất sẽ được chấp nhận 5 ngày sau câu trả lời cuối cùng, tức là nếu không có thêm câu trả lời mới trong vòng 5 ngày, cuộc thi này sẽ kết thúc.


2
Bất kỳ lý do cho các phiếu giảm?
dùng12205

1
Tôi có thể xóa tất cả các khoảng trắng không cần thiết ( s/\s+/ /) và gọi nó là một ngày
ratchet freak

1
@ratchet freak bạn có thể, nhưng tôi không nghĩ rằng đây sẽ là một câu trả lời với rất nhiều upvote.
dùng12205

1
@Quincunx cảm ơn vì đã thiết lập tiền thưởng. Tôi nghĩ rằng câu hỏi của tôi bị hút.
dùng12205

1
@CousinCocaine: đây là một bối cảnh phổ biến. Chúng không được thiết kế để giải quyết vấn đề theo cách thanh lịch hoặc tiêu chuẩn. Chúng được thiết kế để giải quyết vấn đề theo cách tuyệt vời nhất mà bạn có thể tưởng tượng.
SztupY

Câu trả lời:


21

Bởi vì chúng ta đang nói về sự thụt dòng và khoảng trắng, chúng ta chỉ cần viết mã trong một chương trình một ngôn ngữ thực sự được thiết kế xung quanh khoảng trắng , vì điều đó phải dễ nhất, phải không?

Vì vậy, giải pháp là:




















































































































































































































































































































































































































































Đây là cơ sở64:

ICAgCQogICAgCgkJICAgIAkgCiAgICAKCQkgICAgCQkKICAgIAoJCSAgICAJICAKICAgIAoJCSAgICAJIAkKICAgIAoJCSAKIAogCQoKICAgCSAKICAgCQoJCQkgICAJCQkgCQkKCSAgCQoJICAJICAKICAgCQoJCQkgICAJIAkgCgkgIAkKCSAgCSAJCiAgIAkKCQkJICAgCSAgCQoJICAJCgkgIAkgCQogICAJCgkJCSAgIAkgICAgIAoJICAJCgkgIAkgCQogICAJCgkJCSAgIAkJCQkJIAkKCSAgCQoJICAJCSAKICAgCQoJCQkgICAJICAgCSAKCSAgCQoJICAJICAgIAogICAJCgkJCSAgIAkgCSAgIAoJICAJCgkgIAkgICAJCQogICAJCgkJCSAgIAkgCSAgCQoJICAJCgkgIAkgIAkgIAogICAJIAogICAJCgkJIAogCSAJCQkKICAgCQoJCQkJCiAgCgkKCiAgIAkgIAogICAJCgkJCQkKICAKCQoKICAgCSAJCgoJCgogICAJCSAKICAgCQkKICAgCQkKCQkJICAgCQoJICAJCQkgICAgCSAKICAgCQoJCSAKIAkgCQkJCiAgIAkKCQkJCQogIAoJCgogICAJICAgIAogICAJIAogICAJIAoJCSAKIAkgCQkJCiAgIAkKCQkJCQogIAoJCgogICAJICAgCQkKICAgCSAJCiAgIAkgCQoJCQkgICAJCgkgICAJCSAgICAJIAogICAJCgkJIAogCSAJCQkKICAgCQoJCQkJCiAgCgkKCiAgIAkgIAkgIAogICAJIAkKICAgCSAJCgkJCSAgIAkKCSAgCQkJICAgIAkgCiAgIAkKCQkgCiAJIAkJCQogICAJCgkJCQkKICAKCQoKICAgCQkKICAgCQoJCQkgICAJIAkgCgkgIAkKCSAgCQkgIAogICAJCgkJCSAgIAkJCQkgCQkKCSAgCQoJICAJCSAJCiAgIAkKCQkJICAgCQkJCQkgCQoJICAJCgkgIAkJCSAKICAgCQoJCQkgICAJCQkgCQkKCSAgCQoJICAJCQkJCiAgIAkKCQkJICAgCSAgIAkgCgkgIAkKCSAgCQkgCQkKICAgCQoJCQkgICAJIAkgCSAKCSAgCQoJICAJCQkgIAogICAJCgkJCSAgIAkgCQkJCQoJICAJCgkgIAkJCSAJCiAgIAkKCQkJICAgCSAJICAgCgkgIAkKCSAgCSAgCSAJCiAgIAkKCQkJICAgCSAJICAJCgkgIAkKCSAgCSAgCQkgCiAgIAkKCQkJCQogIAoJCgogICAJCSAgCiAgIAkgCiAgICAKCQkgCgkKCiAgIAkJIAkKICAgCQoJCQkJCiAgICAgCSAKICAgIAoJCSAgICAJCQogICAJCQoJCQkgICAJCgkgICAJCSAKCQoKICAgCQkJIAogICAJCQogICAJCQoJCQkgICAJCgkgIAkJCSAKIAkgCQkJCiAgIAkKCQkJCQogICAgIAkgCiAgICAKCQkgCgkKCiAgIAkJCQkKICAgCQoJCQkJCiAgICAgCSAJCgkJCQoJICAJIAkgCgoJCgogICAJICAJCQkKICAgCSAKICAgIAoJCSAKCQoKICAgCQkgCQkKICAgCQoJCQkJCiAgICAgCSAKICAgCSAKCQkgCgkKCiAgIAkJCSAgCiAgIAkgIAoJCQkgICAJIAkJCQkKCSAgCQoJICAJCQkJIAogICAJCgkJCQkKICAKCQoKICAgCQkJIAkKICAgCSAgCgkJCSAgIAkgCQkJCQoJICAJCgkgIAkJCQkJCiAgIAkKCQkJCQogIAoJCgogICAJCQkJIAogICAJCgkJCQkKICAgICAJIAogICAJCQoJCSAKCQoKICAgCQkJCQkKICAgCQoJCQkJCiAgICAgCSAKICAgCSAgCgkJIAoJCgogICAJICAJIAkKICAgCSAJCiAgIAkgCQoJCQkgICAJCgkgICAJCSAgICAJCgkJCQkKICAKCQoKICAgCSAgCQkgCiAgIAkgCQogICAJIAkKCQkJICAgCQoJICAJCQkgICAgCQoJCQkJCiAgCgkKCiAgIAkJCQogICAJIAkgCgkKICAgICAJCQoJCQkKICAgCSAgCQogCiAKCSAgCSAgIAogCiAKCQkgCSAgIAogICAJICAgICAKCQogICAgIAkgICAgIAoJCiAgICAgCQoJICAJCiAKIAkgIAkKCiAgIAkgICAKCgkKCiAgIAkgCSAJCiAgIAkKCQkJICAgCSAJIAoJICAJCgkgIAkJICAgCiAgIAkKCQkJICAgCSAgIAkgCgkgIAkKCSAgCQkgIAkKICAgCQoJCQkJCiAgCgkKCiAgIAkJICAgCiAgIAkgCiAgICAKCQkgCgkKCiAgIAkJICAJCiAgIAkgIAoJCQkgICAJIAkJCSAgCgkgIAkKCSAgCQkgCSAKICAgCSAKICAgCQoJCSAgICAJCgkJCQkKICAKCQoKICAgCQkgCSAKICAgCQoJCQkJCiAgCgkKCiAgIAkgCQkgCiAgIAkKCQkJICAgCSAJCQkJCgkgIAkKCSAgCSAgICAgCiAgIAkKCQkJCQogIAoJCgogICAJICAgICAKICAgCSAgCgkJCSAgIAkgCSAJIAoJICAJCgkgIAkgICAgCQogICAJCgkJCQkKICAKCQoKICAgCSAgICAJCiAgIAkKCQkJCQogICAgIAkgCiAgIAkKCQkgCgkKCiAgIAkgCQkJCiAgIAkKCQkJICAgCSAJIAoJICAJCgkgIAkgICAJIAogICAJCgkJCQkKICAKCQoKICAgCSAgIAkgCiAgIAkgCiAgICAKCQkgCgkKCiAgIAkKICAgCSAgCiAgIAkKCQkJCQkgICAgCQoJCgkgICAgCSAKCQkJCgkgIAkgCSAKICAgCSAKCQkJICAgCQoJICAJCgkgIAkgICAJCiAgIAkgCgkJCSAgIAkgCgkgIAkKCSAgCSAgCSAKICAgCSAKCQkJICAgCQkKCSAgCQoJICAJICAJCQogICAJIAoJCQkgICAJICAKCSAgCQoJICAJIAkgIAoKICAgCSAgIAkKCiAJIAkJCgogCiAJIAkJCgogICAJIAkgCgogCSAJIAoKIAogCSAJCQoKICAgCSAgCSAKCiAJIAkgCSAJCgogCiAJIAkJCgogICAJICAJCQoKIAkgCSAJCSAKCiAKIAkgCQkKCiAgIAkgCSAgCgogCSAJIAkJCQoKICAgCSAJCQoKIAogCQoKCgo=

Đối với những người có vấn đề in mã trên giấy ở đây là phiên bản có chú thích (bạn có thể tìm thấy trình biên dịch cho phần này ở cuối câu trả lời):

# heap structure:
# 1: read buffer
# 2: parser state
#   0: before indentation
#   1: after indentation
#   2: inside a string literal
#   3: inside a multiline comment
#   4: inside a single line comment
# 3: identation
# 4: old read buffer
# 5: parenthesis nesting amount

# -------------------
# initialize heap
# -------------------
SS 1 | SS 0 | TTS # [1] := 0
SS 2 | SS 0 | TTS # [2] := 0
SS 3 | SS 0 | TTS # [3] := 0
SS 4 | SS 0 | TTS # [4] := 0
SS 5 | SS 0 | TTS # [5] := 0
LSL 1 # goto L1

# -------------------
# sub: determine what to do in state 0
# -------------------
LSS 2 # LABEL L2
SS 1 | TTT | SS  59 | TSST | LTS 4 # if [1] == ; GOTO L4
SS 1 | TTT | SS  10 | TSST | LTS 5 # if [1] == \n GOTO L5
SS 1 | TTT | SS   9 | TSST | LTS 5 # if [1] == \t GOTO L5
SS 1 | TTT | SS  32 | TSST | LTS 5 # if [1] == ' ' GOTO L5
SS 1 | TTT | SS 125 | TSST | LTS 6 # if [1] == } GOTO L6
SS 1 | TTT | SS  34 | TSST | LTS 16 # if [1] == " GOTO L16
SS 1 | TTT | SS  40 | TSST | LTS 35 # if [1] == ( GOTO L35
SS 1 | TTT | SS  41 | TSST | LTS 36 # if [1] == ) GOTO L36

SS 2 | SS 1 | TTS # [2] := 1
LST 7 # call L7
SS 1 | TTT | TLSS # print [1]
LTL # return

LSS 4 # label L4 - ; handler
SS 1 | TTT | TLSS # print [1]
LTL # return

LSS 5 # label L5 - WS handler
LTL # return

LSS 6 # label L6 - } handler
# decrease identation by one
SS 3 | SS 3 | TTT | SS 1 | TSST | TTS # [3] := [3] - 1
SS 2 | SS 1 | TTS # [2] := 1
LST 7 # call L7
SS 1 | TTT | TLSS # print [1]
LTL # return

LSS 16 # label L16 - " handler
SS2 | SS 2 | TTS # [2] := 2
LST 7 # call L7
SS1 | TTT | TLSS # print [1]
LTL

LSS 35
SS 5 | SS 5 | TTT | SS 1 | TSSS | TTS # [5] := [5] + 1
SS 2 | SS 1 | TTS # [2] := 1
LST 7 # call L7
SS1 | TTT | TLSS # print [1]
LTL

LSS 36
SS 5 | SS 5 | TTT | SS 1 | TSST | TTS # [5] := [5] - 1
SS 2 | SS 1 | TTS # [2] := 1
LST 7 # call L7
SS1 | TTT | TLSS # print [1]
LTL

# -------------------
# sub: determine what to do in state 1
# -------------------
LSS 3 # LABEL L3
SS 1 | TTT | SS  10 | TSST | LTS 12 # if [1] == \n GOTO L12
SS 1 | TTT | SS 123 | TSST | LTS 13 # if [1] == { GOTO L13
SS 1 | TTT | SS 125 | TSST | LTS 14 # if [1] == } GOTO L14
SS 1 | TTT | SS  59 | TSST | LTS 15 # if [1] == ; GOTO L15
SS 1 | TTT | SS  34 | TSST | LTS 27 # if [1] == " GOTO L27
SS 1 | TTT | SS  42 | TSST | LTS 28 # if [1] == * GOTO L28
SS 1 | TTT | SS  47 | TSST | LTS 29 # if [1] == / GOTO L29
SS 1 | TTT | SS  40 | TSST | LTS 37 # if [1] == ( GOTO L37
SS 1 | TTT | SS  41 | TSST | LTS 38 # if [1] == ) GOTO L38
SS 1 | TTT | TLSS # print [1]
LTL # return

LSS 12 # LABEL L12 - \n handler
SS 2 | SS 0 | TTS # [2] := 0
LTL # return

LSS 13 # LABEL L13 - { handler
SS 1 | TTT | TLSS # print [1]
SS 2 | SS 0 | TTS # [2] := 0
SS 3 | SS 3 | TTT | SS 1 | TSSS | TTS # [3] := [3] + 1
LTL # return

LSS 14 # LABEL L14 - } handler
SS 3 | SS 3 | TTT | SS 1 | TSST | TTS # [3] := [3] - 1
LST 7 # call L7
SS 1 | TTT | TLSS # print [1]
SS 2 | SS 0 | TTS # [2] := 0
LTL # return

LSS 15 # LABEL L15 - ; handler
SS 1 | TTT | TLSS # print [1]
SS 5 | TTT | LTS 10 # if [5] == 0 GOTO L39
LTL

LSS 39
SS 2 | SS 0 | TTS # [2] := 0
LTL # return

LSS 27 # label L27 - " handler
SS1 | TTT | TLSS # print [1]
SS2 | SS 2 | TTS # [2] := 2
LTL

LSS 28 # label L28 - * handler - this might start a comment
SS 4 | TTT | SS  47 | TSST | LTS 30 # if [4] == / GOTO L30
SS1 | TTT | TLSS # print [1]
LTL

LSS 29 # label L29 - / handler - this might start a comment
SS 4 | TTT | SS  47 | TSST | LTS 31 # if [4] == / GOTO L31
SS1 | TTT | TLSS # print [1]
LTL

LSS 30 # label L30 - /* handler
SS1 | TTT | TLSS # print [1]
SS2 | SS 3 | TTS # [2] := 3
LTL

LSS 31 # label L31 - // handler
SS1 | TTT | TLSS # print [1]
SS2 | SS 4 | TTS # [2] := 4
LTL

LSS 37
SS 5 | SS 5 | TTT | SS 1 | TSSS | TTS # [5] := [5] + 1
SS1 | TTT | TLSS # print [1]
LTL

LSS 38
SS 5 | SS 5 | TTT | SS 1 | TSST | TTS # [5] := [5] - 1
SS1 | TTT | TLSS # print [1]
LTL

# -------------------
# sub: print identation
# -------------------
LSS 7 # label L7 - print identation
SS 10 | TLSS # print \n
SS 3 | TTT # push [3]
LSS 9 # label L9 - start loop
SLS | LTS 8 # if [3] == 0 GOTO L8
SLS | LTT 8 # if [3] < 0 GOTO L8 - for safety
SS 32 | TLSS # print ' '
SS 32 | TLSS # print ' '
SS 1  | TSST # i := i - 1
LSL 9 # GOTO L9
LSS 8 # label L8 - end loop
LTL #

# -------------------
# sub: L21 - string literal handler
# -------------------
LSS 21
SS 1 | TTT | SS  10 | TSST | LTS 24 # if [1] == \n GOTO L24
SS 1 | TTT | SS  34 | TSST | LTS 25 # if [1] == " GOTO L25
SS 1 | TTT | TLSS # print [1]
LTL

LSS 24 # \n handler - this should never happen, but let's be prepared and reset the parser
SS 2 | SS 0 | TTS # [2] := 0
LTL # return

LSS 25 # " handler - this might be escaped, so be prepared
SS 4 | TTT | SS  92 | TSST | LTS 26 # if [4] == \ GOTO L26
SS 2 | SS 1 | TTS # [2] := 1
SS 1 | TTT | TLSS # print [1]
LTL

LSS 26 # \\" handler - escaped quotes don't finish the literal
SS 1 | TTT | TLSS # print [1]
LTL

# -------------------
# sub: L22 - multiline comment handler
# -------------------
LSS 22
SS 1 | TTT | SS  47 | TSST | LTS 32 # if [1] == / GOTO L32
SS 1 | TTT | TLSS # print [1]
LTL

LSS 32
SS 4 | TTT | SS  42 | TSST | LTS 33 # if [4] == * GOTO L33
SS 1 | TTT | TLSS # print [1]
LTL

LSS 33
SS 1 | TTT | TLSS # print [1]
SS 2 | SS 1 | TTS # [2] := 1
LTL
# -------------------
# sub: L23 - singleline comment handler
# -------------------
LSS 23
SS 1 | TTT | SS  10 | TSST | LTS 34 # if [1] == \n GOTO L34
SS 1 | TTT | TLSS # print [1]
LTL

LSS 34
SS 2 | SS 0 | TTS # [2] := 0
LTL

# -------------------
# main loop
# -------------------
LSS 1 # LABEL L1
SS 4 | SS 1 | TTT | TTS # [4] := [1]
SS 1 | TLTS # [1] := read

SS 2 | TTT | LTS 10 # if [2] == 0 GOTO L10
SS 2 | TTT | SS 1 | TSST | LTS 17 # if [2] == 1 GOTO L17
SS 2 | TTT | SS 2 | TSST | LTS 18 # if [2] == 2 GOTO L18
SS 2 | TTT | SS 3 | TSST | LTS 19 # if [2] == 3 GOTO L19
SS 2 | TTT | SS 4 | TSST | LTS 20 # if [2] == 4 GOTO L20

LSS 17
LST 3  # call L3
LSL 11 # GOTO L11

LSS 10 # label L10
LST 2  # call L2
LSL 11

LSS 18
LST 21
LSL 11

LSS 19
LST 22
LSL 11

LSS 20
LST 23

LSS 11 # label L11
LSL 1  # goto L1
LLL # END

Điều này vẫn đang được tiến hành, mặc dù hy vọng nó sẽ vượt qua hầu hết các tiêu chí!

Các tính năng hiện được hỗ trợ:

  • sửa lỗi nhận dạng dựa trên {}ký tự.
  • thêm một dòng mới sau ;
  • xử lý các ký tự thụt bên trong chuỗi ký tự (bao gồm cả thực tế là chuỗi ký tự không bị đóng khi gặp a \")
  • xử lý các ký tự thụt vào trong các bình luận đơn và đa dòng
  • không thêm các ký tự dòng mới nếu bên trong dấu ngoặc đơn (như một forkhối)

Ví dụ đầu vào (Tôi đã thêm một số trường hợp cạnh dựa trên nhận xét của Quincunx, để bạn có thể kiểm tra xem nó có hoạt động đúng không):

    /* Hai Worldz. This code is to prevent formatting: if(this_code_is_touched){,then+your*program_"doesn't({work)}correctl"y.} */
#include<stdio.h>
#include<string.h>
int main() {
int i;
char s[99];
     printf("----------------------\n;;What is your name?;;\n----------------------\n\""); //Semicolon added in the {;} string just to annoy you
             /* Now we take the {;} input: */
    scanf("%s",s);
    for(i=0;i<strlen(s);i++){if(s[i]>='a'&&s[i]<='z'){
        s[i]-=('a'-'A'); //this is same as s[i]=s[i]-'a'+'A'
}}printf("Your \"name\" in upper case is:\n%s\n",s);
   return 0;}

Ví dụ đầu ra:

[~/projects/indent]$ cat example.c | ./wspace indent.ws 2>/dev/null

/* Hai Worldz. This code is to prevent formatting: if(this_code_is_touched){,then+your*program_"doesn't({work)}correctl"y.} */
#include<stdio.h>
#include<string.h>
int main() {
  int i;;
  char s[99];;
  printf("----------------------\n;;What is your name?;;\n----------------------\n\"");; //Semicolon added in the {;} string just to annoy you
  /* Now we take the {;} input: */
  scanf("%s",s);;
  for(i=0;i<strlen(s);i++){
    if(s[i]>='a'&&s[i]<='z'){
      s[i]-=('a'-'A');; //this is same as s[i]=s[i]-'a'+'A'
    }
  }
  printf("Your \"name\" in upper case is:\n%s\n",s);;
  return 0;;
}

Lưu ý rằng bởi vì khoảng trắng không hỗ trợ EOF kiểm tra intepreter ném ngoại lệ, mà chúng ta cần phải triệt tiêu. Vì không có cách nào trong khoảng trắng để kiểm tra EOF (theo như tôi biết vì đây là chương trình khoảng trắng đầu tiên của tôi) nên đây là điều không thể tránh khỏi, tôi hy vọng giải pháp vẫn được tính.

Đây là tập lệnh tôi đã sử dụng để biên dịch phiên bản chú thích thành khoảng trắng phù hợp:

#!/usr/bin/env ruby
ARGF.each_line do |line|
  data = line.gsub(/'.'/) { |match| match[1].ord }
  data = data.gsub(/[^-LST0-9#]/,'').split('#').first
  if data
    data.tr!('LST',"\n \t")
    data.gsub!(/[-0-9]+/){|m| "#{m.to_i<0?"\t":" "}#{m.to_i.abs.to_s(2).tr('01'," \t")}\n" }
    print data
  end
end

Chạy:

./wscompiler.rb annotated.ws > indent.ws

Lưu ý rằng điều này, ngoài việc chuyển đổi S, LTnhân vật, cũng cho phép bình luận dòng duy nhất với #, và có thể tự động chuyển đổi số và chữ nhân vật đơn giản thành đại diện khoảng trắng của họ. Hãy sử dụng nó cho các dự án khoảng trắng khác nếu bạn muốn


Không tệ! :) nhưng sẽ tốt hơn nếu nó không chia một vòng lặp for thành ba dòng (theo ý kiến ​​của tôi ít nhất ... nó vẫn tùy thuộc vào các cử tri quyết định). Xin nhắc lại, vòng lặp for trong C có cú phápfor(i=0;i<10;i++)
user12205

2
@ace: vì Whitespace không chính xác là một ngôn ngữ cấp cao thêm các loại ngoại lệ này không phải là dễ dàng. Điều đó nói rằng tôi vẫn cố gắng khắc phục hai vấn đề với các bình luận và nghĩa đen, và cố gắng quản lý để sửa các vòng lặp (tôi nghĩ bỏ qua ;bên trong (/ )khối là đủ). Tôi nghĩ rằng những điều đó là đủ để xem xét giải pháp "có thể sử dụng".
SztupY

1
@ace: Tôi nghĩ rằng tôi đã quản lý để thêm các ngoại lệ, vì vậy bây giờ mã được tạo dường như được thụt lề đúng cách. Thay đổi ví dụ thành ví dụ của bạn
SztupY

9

Vim một cách dễ dàng, về mặt kỹ thuật chỉ sử dụng một ký tự:=

Tôi không phải là một vim guru, nhưng tôi không bao giờ đánh giá thấp sức mạnh của nó và một số người coi nó như một ngôn ngữ lập trình. Đối với tôi giải pháp này là một người chiến thắng nào.

Mở tệp trong vim:

vim file.c

Trong vim nhấn các phím sau

gg=G

Giải trình:

gg đi đến đầu tập tin

= là một lệnh để sửa vết lõm

G nói với nó để thực hiện các hoạt động đến cuối tập tin.

Bạn có thể lưu và thoát với :wq

Có thể để vimchạy lệnh từ dòng lệnh, vì vậy điều này cũng có thể được thực hiện trong một lớp lót, nhưng tôi để điều đó cho những người hiểu vimrõ hơn tôi.


Vim ví dụ một tệp đầu vào hợp lệ (Dailymotion.c) với thụt lề xấu.

/* Fibonacci Series c language */
#include<stdio.h>

int main()
{
int n, first = 0, second = 1, next, c;

            printf("Enter the number of terms\n");
scanf("%d",&n);
  printf("First %d terms of Fibonacci series are :-\n",n);

          for ( c = 0 ; c < n ; c++ )
   {
if ( c <= 1 )
         next = c;
 else
                                     {
next = first +    second;
              first = second;
        second = next;
      }
      printf("%d\n",next);
   }
 return 0;
}

Mở trong vim: vim fibonacci.cnhấngg=G

/* Fibonacci Series c language */
#include<stdio.h>

int main()
{
  int n, first = 0, second = 1, next, c;

  printf("Enter the number of terms\n");
  scanf("%d",&n);
  printf("First %d terms of Fibonacci series are :-\n",n);

  for ( c = 0 ; c < n ; c++ )
  {
    if ( c <= 1 )
      next = c;
    else
    {
      next = first +    second;
      first = second;
      second = next;
    }
    printf("%d\n",next);
  }
  return 0;
}


Điều này có thể được rút ngắn để =GZZ. (Vim golf ftw!)
Doorknob

7

Vì điều này sẽ được sử dụng để giúp giáo viên hiểu mã của học sinh tốt hơn, điều quan trọng là phải vệ sinh đầu vào trước. Các chỉ thị tiền xử lý không được xem xét, vì chúng chỉ xâm nhập vào sự lộn xộn và các macro cũng có thể đưa mã độc vào tệp. Chúng tôi không muốn điều đó! Ngoài ra, việc giữ lại những bình luận ban đầu mà sinh viên đã viết là hoàn toàn không cần thiết, vì dù sao chúng có lẽ hoàn toàn vô dụng.

Thay vào đó, như mọi người đều biết mã tốt cần bình luận tốt, ngoài việc sửa lỗi thụt lề và cấu trúc, tại sao không thêm một số nhận xét rất hữu ích xung quanh các điểm chính của mã để làm cho kết quả thậm chí dễ hiểu hơn! Điều này chắc chắn sẽ giúp giáo viên trong việc đánh giá công việc mà học sinh đã làm!

Vì vậy, từ đây:

    /* Hai Worldz. This code is to prevent formatting: if(this_code_is_touched){,then+your*program_"doesn't({work)}correctl"y.} */
#include<stdio.h>
#include<string.h>
int main() {
int i;
char s[99];
     printf("----------------------\n;;What is your name?;;\n----------------------\n\""); //Semicolon added in the {;} string just to annoy you
             /* Now we take the {;} input: */
    scanf("%s",s);
    for(i=0;i<strlen(s);i++){if(s[i]>='a'&&s[i]<='z'){
        s[i]-=('a'-'A'); //this is same as s[i]=s[i]-'a'+'A'
}}printf("Your \"name\" in upper case is:\n%s\n",s);
   return 0;}

Hãy sản xuất cái này:

int main() {
    /* This will declare i. */
    int i;
    /* This will declare s[99]. */
    char s[99];
    /* This will call the function called printf with 1 parameters */
    printf("----------------------\n;;What is your name?;;\n----------------------\n\"");
    /* This will call the function called scanf with 2 parameters */
    scanf("%s", s);
    /* This will start a for loop, with initializator i = 0. It will loop until i < strlen(s), and will i++ at each iteration */
    for (i = 0; i < strlen(s); i++) {
        /* This will check, whether s[i] >= 'a' && s[i] <= 'z' is true or not. */
        if (s[i] >= 'a' && s[i] <= 'z') {
            s[i] -= 'a' - 'A';
        }
    }
    /* This will call the function called printf with 2 parameters */
    printf("Your \"name\" in upper case is:\n%s\n", s);
    /* This will return from the function. */
    return 0;
}

Không phải là tốt hơn nhiều, với tất cả các ý kiến ​​hữu ích xung quanh các biểu thức?


Vì vậy, đây là một giải pháp ruby sử dụng castđá quý, đó là một trình phân tích cú pháp C (Có, tôi đang gian lận) . Vì điều này sẽ phân tích mã và in lại từ đầu, điều đó có nghĩa là kết quả sẽ được thụt lề hoàn hảo và cũng nhất quán, ví dụ:

  • Việc thụt lề đúng trên mã dựa trên cấp độ khối
  • Khoảng trắng nhất quán xung quanh biểu thức, phát biểu, điều kiện, v.v.
  • Hoàn thành thụt lề dựa trên cấu trúc của mã
  • Vân vân.

Và nó cũng sẽ chứa các bình luận rất hữu ích về cách thức hoạt động của mã, điều này sẽ siêu hữu ích cho cả học sinh và giáo viên!

indent.rb

#!/usr/bin/env ruby
require 'cast'

code = ''
ARGF.each_line do |line|
  if line=~/\A#/
    code << "// #{line.strip}\n"
  else
    code << line
  end
end

class Comment < C::Literal
  field :val
  initializer :val
  def to_s
    "/* #{val} */"
  end
end

tree = C.parse(code)
tree.preorder do |n|
  break if n.kind_of?(Comment)
  if n.kind_of?(C::Declaration)
    dd = []
    n.declarators.each do |d|
      dd << "declare #{d.indirect_type ? d.indirect_type.to_s(d.name) : d.name}"
      dd.last << " and set it to #{d.init}" if d.init
    end
    unless dd.empty?
      n.insert_prev(Comment.new("This will #{dd.join(", ")}."))
    end
  end rescue nil
  n.parent.insert_prev(Comment.new("This will call the function called #{n.expr} with #{n.args.length} parameters")) if n.kind_of?(C::Call) rescue nil
  n.insert_prev(Comment.new("This will start a for loop, with initializator #{n.init}. It will loop until #{n.cond}, and will #{n.iter} at each iteration")) if n.kind_of?(C::For) rescue nil
  n.insert_prev(Comment.new("This will check, whether #{n.cond} is true or not.")) if n.kind_of?(C::If) rescue nil
  n.insert_prev(Comment.new("This will return from the function.")) if n.kind_of?(C::Return) rescue nil
end

puts tree

Gemfile

source "http://rubygems.org"
gem 'cast', '0.2.1'

3
+1 choit is completely unnecessary to retain the original comments the student wrote, as they are probably completely useless anyway
SeinopSys

Những bình luận đó là không mô tả cho tôi. Họ giới thiệu sự lộn xộn bởi vì họ chỉ đơn giản là lặp lại các dòng sau.
Justin

@Quincunx Tôi nghĩ bạn đã bỏ lỡ thẻ châm biếm. Đây là một cuộc thi phổ biến.
SztupY

5

Bash, 35 ký tự

Tệp đầu vào phải được đặt tên là "input.c" và được đặt trong thư mục làm việc hiện tại.

sh <(wget -q -O- http://x.co/3snpk)

Ví dụ đầu ra, đã được cung cấp đầu vào trong câu hỏi ban đầu: http://i.imgur.com/JEI8wa9.png

Có thể mất vài giây để chạy tùy thuộc vào phần cứng của bạn, vì vậy hãy kiên nhẫn :)


Bạn biết rằng đây không phải là môn đánh gôn, phải không?
Justin

1
+1 để tải xuống và biên dịch AStyle khi đang bay Oo bạn sẽ không để AStyle ở đó để thuận tiện cho người dùng chứ? Vì vậy, loại bỏ rm?
tomsmeding

Vì đây không phải là môn đánh gôn, tôi nghĩ sẽ tốt hơn nếu chỉ đặt nội dung của pastebin của bạn ở đây, vì nhìn nhanh tôi thậm chí không nhận thấy bạn đang thực sự định dạng mã đúng bằng lệnh bên ngoài
SztupY

@Quincunx: nó có nghĩa là một câu trả lời troll: P
Riot

@tomsmeding: Tôi không muốn mã của mình có tác dụng phụ, chẳng hạn như chiếm không gian đĩa của người dùng một cách bất ngờ ...
Riot

3

Hồng ngọc

code = DATA.read

# first, we need to replace strings and comments with tilde escapes to avoid parsing them
code.gsub! '~', '~T'
lineComments = []
code.gsub!(/\/\/.*$/) { lineComments.push $&; '~L' }
multilineComments = []
code.gsub!(/\/\*.*?\*\//m) { multilineComments.push $&; '~M' }
strs = []
code.gsub!(/"(\\.|[^"])*"|'.'/) { strs.push $&; '~S' } # character literals are considered strings

# also, chop out preprocessor stuffs
preprocessor = ''
code.gsub!(/(^#.*\n)+/) { preprocessor = $&; '' }

# clean up newlines and excess whitespace
code.gsub! "\n", ' '
code.gsub! /\s+/, ' '
code.gsub!(/[;{}]/) { "#{$&}\n" }
code.gsub!(/[}]/) { "\n#{$&}" }
code.gsub! /^\s*/, ''
code.gsub! /\s+$/, ''

# fix for loops (with semicolons)
code.gsub!(/^for.*\n.*\n.*/) { $&.gsub ";\n", '; ' }

# now it's time for indenting; add indent according to {}
indentedCode = ''
code.each_line { |l|
    indentedCode += ('    ' * [indentedCode.count('{') - indentedCode.count('}') - (l =~ /^\}/ ? 1 : 0), 0].max) + l
}
code = indentedCode

# finally we're adding whitespace for more readability. first get a list of all operators
opsWithEq = '= + - * / % ! > < & | ^ >> <<'
opsNoEq = '++ -- && ||'
ops = opsWithEq.split + opsWithEq.split.map{|o| o + '=' } + opsNoEq.split
ops = ops.sort_by(&:length).reverse
# now whitespace-ize them
code.gsub!(/(.)(#{ops.map{|o| Regexp.escape o }.join '|'})(.)/m) { "#{$1 == ' ' ? ' ' : ($1 + ' ')}#{$2}#{$3 == ' ' ? ' ' : (' ' + $3)}" }

# special-cases: only add whitespace to the right
ops = ','.split
code.gsub!(/(#{ops.map{|o| Regexp.escape o }.join '|'})(.)/m) { "#{$1}#{$2 == ' ' ? ' ' : (' ' + $2)}" }
# special-cases: only add whitespace to the left
ops = '{'.split
code.gsub!(/(.)(#{ops.map{|o| Regexp.escape o }.join '|'})/m) { "#{$1 == ' ' ? ' ' : ($1 + ' ')}#{$2}" }

# replace the tilde escapes and preprocessor stuffs
stri = lci = mci = -1
code.gsub!(/~(.)/) {
    case $1
    when 'T'
        '~'
    when 'S'
        strs[stri += 1]
    when 'L'
        lineComments[lci += 1] + "\n#{code[0, $~.begin(0)].split("\n").last}"
    when 'M'
        multilineComments[mci += 1]
    end
}
code = (preprocessor + "\n" + code).gsub /^ +\n/, ''

puts code
__END__
    /* Hai Worldz. This code is to prevent formatting: if(this_code_is_touched){,then+your*program_"doesn't({work)}correctl"y.} */
#include<stdio.h>
#include<string.h>
int main() {
int i;
char s[99];
     printf("----------------------\n;;What is your name?;;\n----------------------\n\""); //Semicolon added in the {;} string just to annoy you
             /* Now we take the {;} input: */
    scanf("%s",s);
    for(i=0;i<strlen(s);i++){if(s[i]>='a'&&s[i]<='z'){
        s[i]-=('a'-'A'); //this is same as s[i]=s[i]-'a'+'A'
}}printf("Your \"name\" in upper case is:\n%s\n",s);
   return 0;}

Đầu ra:

#include <stdio.h>
#include<string.h>

int main() {
    int i;
    char s[99];
    printf("----------------------\n;;What is your name?;;\n----------------------\n");
    //Semicolon added in the string just to annoy you
     /* Now we take the input: */ scanf("%s", s);
    for(i = 0; i < strlen(s); i ++ ) {
        if(s[i] >= 'a' && s[i] <= 'z') {
            s[i] -= ('a' - 'A');
            //this is same as s[i]=s[i]-'a'+'A'
        }
    }
    printf("Your name in upper case is:\n%s\n", s);
    return 0;
}

Đầu ra cho đầu vào trường hợp cạnh của @ SztupY:

#include<stdio.h>
#include<string.h>

/* Hai Worldz. This code is to prevent formatting: if(this_code_is_touched){,then+your*program_"doesn't({work)}correctl"y.} */ int main() {
    int i;
    char s[99];
    printf("----------------------\n;;What is your name?;;\n----------------------\n\"");
    //Semicolon added in the {;} string just to annoy you
     /* Now we take the {;} input: */ scanf("%s", s);
    for(i = 0; i < strlen(s); i ++ ) {
        if(s[i] >= 'a' && s[i] <= 'z') {
            s[i] -= ('a' - 'A');
            //this is same as s[i]=s[i]-'a'+'A'
        }
    }
    printf("Your \"name\" in upper case is:\n%s\n", s);
    return 0;
}

Các tính năng cho đến nay:

  • [x] Thêm thụt lề thích hợp ở phía trước của mỗi dòng
  • [x]Thêm khoảng trắng sau ,và các toán tử khác, ví dụ: chuyển đổi int a[]={1,2,3};sang int a[] = {1, 2, 3};. Hãy nhớ không xử lý các toán tử trong chuỗi ký tự mặc dù.
  • [x] Xóa dấu cách sau mỗi dòng
  • [x]Tách các câu thành nhiều dòng, ví dụ học sinh có thể viết tmp=a;a=b;b=tmp;hoặc int f(int n){if(n==1||n==2)return 1;else return f(n-1)+f(n-2);}tất cả trong một dòng, bạn có thể tách chúng thành các dòng khác nhau. forMặc dù vậy, hãy chú ý đến các vòng lặp, chúng có dấu chấm phẩy trong đó nhưng tôi thực sự không nghĩ bạn nên tách chúng ra.
  • [ ] Thêm một dòng mới sau khi xác định từng chức năng
  • [ ] Một tính năng khác mà bạn có thể đưa ra với sự giúp đỡ bạn hiểu được mã của học sinh.

3

Điều này được viết bằng python và dựa trên các tiêu chuẩn mã hóa GNU.

Các tính năng cho đến nay:

  • Khối thụt
  • Tách dòng (có thể chia những thứ không nên)
  • Định nghĩa hàm kiểu GNU

Mã số:

import sys

file_in = sys.argv[1]

# Functions, for, if, while, and switch statements
def func_def(string):
    ret = ["", "", ""]
    func_name = ""
    paren_level = -1
    consume_id = False

    for x in string[::-1]:
        if x == "{":
            ret[2] = "{"
        elif ret[1] == "":
            if x == "(":
                paren_level -= 1
                func_name += x
            elif x == ")":
                paren_level += 1
                func_name += x
            elif paren_level == -1 and x.isspace():
                if consume_id:
                    ret[1] = func_name[::-1]
            elif paren_level == -1:
                consume_id = True
                func_name += x
            else:
                func_name += x
        else:
            # Return Type
            ret[0] += x
    else:
        ret[1] = func_name[::-1]

    ret[0] = ret[0][::-1]

    # Handle the case in which this is just a statement
    if ret[1].split("(")[0].strip() in ["for", "if", "while", "switch"]:
        ret = [ret[1], ret[2]] # Don't print an extra line

    return ret

with open(file_in) as file_obj_in:
    line_len = 0
    buffer = ""
    in_str = False
    no_newline = False
    indent_level = 0
    tab = " " * 4
    no_tab = False
    brace_stack = [-1]

    while True:
        buffer += file_obj_in.read(1)
        if buffer == "":
            break
        elif "\n" in buffer:
            if not no_newline:
                print(("" if no_tab else indent_level * tab) + buffer, end="")
                buffer = ""
                line_len = indent_level * 4
                no_tab = False
                continue
            else:
                buffer = ""
                line_len = indent_level * 4
                no_newline = False
                continue
        elif buffer[-1] == '"':
            in_str = not in_str
        elif buffer.isspace():
            buffer = ""
            continue

        if "){" in "".join(buffer.split()) and not in_str:
            for x in func_def(buffer):
                print(indent_level * tab + x)
            buffer = ""
            line_len = indent_level * 4
            no_newline = True
            indent_level += 1
            brace_stack[0] += 1
            brace_stack.append((brace_stack[0], True))
            continue
        elif buffer[-1] == "}" and not in_str:
            brace_stack[0] -= 1
            if brace_stack[-1][1]: # If we must print newline and indent
                if not buffer == "}":
                    print(indent_level * tab + buffer[:-1].rstrip("\n"))
                indent_level -= 1
                print(indent_level * tab + "}")
                buffer = ""
                line_len = indent_level * 4
            else:
                pass
            brace_stack.pop()
        line_len += 1

        if line_len == 79 and not in_str:
            print(indent_level * tab + buffer)
            buffer = ""
            line_len = indent_level * 4
            continue
        elif line_len == 78 and in_str:
            print(indent_level * tab + buffer + "\\")
            buffer = ""
            line_len = indent_level * 4
            no_tab = True
            continue

Ví dụ đầu vào (truyền tên tệp làm đối số):

#include <stdio.h>
#include<string.h>
int main() {
int i;
char s[99];
     printf("----------------------\n;;What is your name?;;\n----------------------\n"); //Semicolon added in the string just to annoy you
             /* Now we take the input: */
    scanf("%s",s);
    for(i=0;i<strlen(s);i++){if(s[i]>='a'&&s[i]<='z'){
        s[i]-=('a'-'A'); //this is same as s[i]=s[i]-'a'+'A'
}}printf("Your name in upper case is:\n%s\n",s);
   return 0;}

Ví dụ đầu ra:

#include <stdio.h>
#include<string.h>
int
main()
{
    int i;
    char s[99];
    printf("----------------------\n;;What is your name?;;\n------------------\
----\n"); //Semicolon added in the string just to annoy you
    /* Now we take the input: */
    scanf("%s",s);
    for(i=0;i<strlen(s);i++)
    {
        if(s[i]>='a'&&s[i]<='z')
        {
            s[i]-=('a'-'A'); //this is same as s[i]=s[i]-'a'+'A'
        }
    }
    printf("Your name in upper case is:\n%s\n",s);
    return 0;
}

Điều này sẽ có lỗi.


0

.Mạng lưới

Mở tệp đó bằng Visual Studio

Đầu vào:

#include<stdio.h>
#include<string.h>
int main() {
int i;
char s[99];
     printf("----------------------\n;;What is your name?;;\n----------------------\n\""); //Semicolon added in the {;} string just to annoy you
             /* Now we take the {;} input: */
    scanf("%s",s);
    for(i=0;i<strlen(s);i++){if(s[i]>='a'&&s[i]<='z'){
            s[i]-=('a'-'A'); //this is same as s[i]=s[i]-'a'+'A'
    }
}printf("Your \"name\" in upper case is:\n%s\n",s);
       return 0;}

Đầu ra:

nhập mô tả hình ảnh ở đây


2
Đây là một ý tưởng tốt, nhưng thách thức là một cuộc thi lập trình. Bạn có thể viết một chương trình mở tập tin này bằng các studio trực quan, sau đó lưu nó trong bản in đẹp không?
Justin
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.