2016-02-29 43 views
-1

我正在做一件作業,需要我從一段彙編語言中刪除空白以及分號後的註釋。例如mov %a,0x01 ; blah blah blah。我希望能夠在分號之前將所有字符存儲在數組中並打印出來。任何想法如何做,因爲我是一個C noob。存儲從fgetc獲得的字符

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

int main(int argc, char *argv[]) { 
    char ch; 
    int i; 
    //char line[] = "mov %a,0x01  ; system call number (sys_exit)\n"; 
    char label[100]; 
    char *infilename = argv[1]; 
    int length = strlen(line); 

    FILE *infile = fopen(infilename, "rb"); 

    printf("   "); 
    while (1) { 
     ch = fgetc(infile); 
     if (ch == EOF) 
      break; 

     if (isspace(ch) == 0) { 
      printf("%c", ch);    
     } 
    } 
    fclose(infile); 
    return 0; 
} 
+0

實際上沒有必要存儲字符,你可以決定是否需要打印或不馬上。 – Jester

+0

@Jester你可能是對的,但在作業方面,通常需要和需求之間存在差異。 – mah

+0

您也想刪除'%a,0x01'和';'之間的空格。但是將'mov'和'%a,0x01'之間的空格限制在一個空格內。 –

回答

2

一個簡單的狀態機:傳入的文本是評論的一部分嗎?

無需保存該行,只需在到達時進行打印。

bool IsComment = false; 
int ch; // Insure to use type `int` for proper `EOF` compare and `isspace()` usage. 
while ((ch = fgetc(infile)) != EOF) { 
    if (IsComment) { 
    if (ch == '\n') { 
     IsComment = false; 
     fputc(ch, stdout); // end comment 
    } 
    } else if (isspace(ch) && ch != '\n') { 
    ; // do not print space 
    } else if (ch == ';') { 
    IsComment = true; // start comment 
    } else { 
    fputc(ch, stdout); 
    } 
} 
+0

爲使EOF測試能夠可靠地工作,ch必須爲int – chqrlie

+0

@chqrlie同意'ch'需要是'int',因爲在這個答案中不僅對於'EOF'的正確測試,而且對於便攜式使用'isspace()'。 – chux

+0

確實'isspace()'不應該用'char'參數調用。 – chqrlie

1

ch應該被定義爲int因此值EOF可被存儲並從文件結束之前返回的所有unsigned char值區別開來。

此外,行int length = strlen(line);指的是未定義的變量line

下面是一個更完整的版本:

#include <stdio.h> 
#include <ctype.h> 

int main(int argc, char *argv[]) { 
    int ch, filter = 0, prefix = 1; 
    char *infilename = argv[1]; 
    FILE *infile = fopen(infilename, "r"); 

    if (infile != NULL) { 
     while ((ch = fgetc(infile)) != EOF) { 
      if (prefix) { 
       prefix = 0; 
       printf("   "); // print the line prefix 
      } 
      if (ch == ';') { 
       filter = 1; // filter characters until \n 
      } else 
      if (ch == '\n') { 
       filter = 0; // end of line: reset filter 
       prefix = 1; // and will print the prefix on next line 
       putchar(ch); 
      } else 
      if (!filter && !isspace(ch)) { 
       putchar(ch); // output character unless filtered   
      } 
     } 
     fclose(infile); 
    } 
    return 0; 
} 

注:

  • filter是一個布爾變量,其確定是否字符應當輸出與否。默認情況下,filter=0,所以字符輸出,除非他們是白色的空間。如果讀取的字符是;,則過濾器設置爲1,因此將;和以下字符過濾出來,直到行結束,該過濾器未被過濾掉。該計劃實施評論刪除。
  • prefix是一個布爾變量,設置在文件的開始位置,每行換行後告訴循環在輸出任何字符之前在下一行的開頭輸出一個" "。我推斷你想在你的代碼循環之前從printf(" ");得到這種行爲,但它可能出於不同的目的。
  • 這個簡單的過濾器可能不正確,因爲它會刪除所有空格字符,包括字符串文字中的字符。它還假設;總是引入評論,但;在字符串文字中不會...您可能需要了解更多的彙編語法才能正確實現此過濾器。
+0

也許你的意思是'ch'而不是'c'? –

+1

@MichaelPetch:當然......我會在'ch'上選擇'c',我的手指也是如此。 – chqrlie

+0

嗨,感謝您的全面回覆,但您能解釋過濾器和前綴的用法嗎? – Jim