C

為什麼 GNU Indent 會折疊一層縮進?

  • January 18, 2019

當我嘗試使用GNU Indent格式化我的 C 程式碼時,它似乎無法處理多層嵌套縮進。具體來說,它似乎折疊了第二級縮進。

例如,如果這是我開始的程式碼:

#include <stdio.h>

int main(int argc, char *argv[])
{
   int n;

   if (argc > 1) {
       printf("# of args: %d\n", argc);
   }

   for (n = 1; n <= 15; n++) {
       if (n % 3 == 0) {
           printf("fizz %d\n", n);
       } else if (n % 5 == 0) {
           printf("buzz %d\n", n);
       } else if (n % 3 == 0 && n % 5 == 0) {
           printf("fizzbuzz %d\n", n);
       } else {
           printf("%d\n", n);
       }
   }

   return 0;
}

如果我執行indent -kr fizzbuzz.c,我會得到這個:

#include <stdio.h>

int main(int argc, char *argv[])
{
   int n;

   if (argc > 1) {
   printf("# of args: %d\n", argc);
   }

   for (n = 1; n <= 15; n++) {
   if (n % 3 == 0) {
       printf("fizz %d\n", n);
   } else if (n % 5 == 0) {
       printf("buzz %d\n", n);
   } else if (n % 3 == 0 && n % 5 == 0) {
       printf("fizzbuzz %d\n", n);
   } else {
       printf("%d\n", n);
   }
   }

   return 0;
}

如果我只使用預設值 ( indent fizzbuzz.c) 執行它,我會得到:

#include <stdio.h>

int
main (int argc, char *argv[])
{
 int n;

 if (argc > 1)
   {
     printf ("# of args: %d\n", argc);
   }

 for (n = 1; n <= 15; n++)
   {
     if (n % 3 == 0)
   {
     printf ("fizz %d\n", n);
   }
     else if (n % 5 == 0)
   {
     printf ("buzz %d\n", n);
   }
     else if (n % 3 == 0 && n % 5 == 0)
   {
     printf ("fizzbuzz %d\n", n);
   }
     else
   {
     printf ("%d\n", n);
   }
   }

 return 0;
}

似乎如果它是開箱即用的,很多人會問它,因為如果它不是錯誤,那麼格式化程式碼似乎是一種非常奇怪的方式。為什麼這樣做?

我正在使用 GNU Indent 的 2.2.11 版本。

它使用混合空格和(8 個空格)製表符來縮進。您可以通過這個最小的範例看到這一點:

int main() {
   if (true) {
       while (false) {
           puts("");
       }
   }
}

如果我執行它indent -kr然後hexdump -C,我得到這個:

$ indent -kr < mini.c |hexdump -C
00000000  69 6e 74 20 6d 61 69 6e  28 29 0a 7b 0a 20 20 20  |int main().{.   |
00000010  20 69 66 20 28 74 72 75  65 29 20 7b 0a 09 77 68  | if (true) {..wh|
00000020  69 6c 65 20 28 66 61 6c  73 65 29 20 7b 0a 09 20  |ile (false) {.. |
00000030  20 20 20 70 75 74 73 28  22 22 29 3b 0a 09 7d 0a  |   puts("");..}.|
00000040  20 20 20 20 7d 0a 7d 0a                           |    }.}.|
00000048

您可以看到,while前面有一個09(水平製表符)字節,而puts前面有一個製表符和四個空格(20)。預設類似:

00000000  69 6e 74 0a 6d 61 69 6e  20 28 29 0a 7b 0a 20 20  |int.main ().{.  |
00000010  69 66 20 28 74 72 75 65  29 0a 20 20 20 20 7b 0a  |if (true).    {.|
00000020  20 20 20 20 20 20 77 68  69 6c 65 20 28 66 61 6c  |      while (fal|
00000030  73 65 29 0a 09 7b 0a 09  20 20 70 75 74 73 20 28  |se)..{..  puts (|
00000040  22 22 29 3b 0a 09 7d 0a  20 20 20 20 7d 0a 7d 0a  |"");..}.    }.}.|
00000050

雖然在這裡,只有最裡面的大括號並puts得到一個標籤。

您可以使用-nut/--no-tabs選項在任何地方使用空格:

$ indent -kr -nut fizzbuzz.c

或者,如果堅持原始縮進很重要,您可以將編輯器和/或終端配置為使用 8 個寬的製表符而不是 4 個製表符。該expand命令可能有助於轉換您不想重新縮進的現有文件。

引用自:https://unix.stackexchange.com/questions/495349