簡體   English   中英

沒有初始打印語句,循環中的 Printf 不起作用

[英]Printf in loop not working without initial print statement

我正在嘗試用 C 編寫一個非常基本的詞法分析器,並具有以下代碼,該代碼應該執行以下操作:

輸入: "12 142 123"

輸出:

NUMBER -- 12
NUMBER -- 14
NUMBER -- 123

但是,我遇到了一個問題,如果在循環輸入之前不包含初始printf("")語句,那么我將得到如下輸出:

NUMBER --
NUMBER -- 14
NUMBER -- 123

其中第一個數字只是空白。 我真的很困惑為什么會發生這種情況,並且非常感謝您的幫助!

我有以下代碼(省略了一些不相關的功能)

#define MAX_LEN 400

char* input;
char* ptr;

char curr_type;
char curr;

enum token_type {
  END,
  NUMBER,
  UNEXPECTED
};

typedef struct {
  enum token_type type;
  char* str;
} Token;
  
void print_tok(Token t) {
  printf("%s -- %s\n", token_types[t.type], t.str);
}

char get(void) {
  return *ptr++;
}

char peek(void) {
  return *ptr;
}

Token number(void) {
  char arr[MAX_LEN];
  arr[0] = peek();
  get();
  int i = 1;
  while (is_digit(peek())) {
    arr[i] = get();
    ++i;
  }
  arr[++i] = '\0';
  Token ret = {NUMBER, (char*)arr};
  return ret;
}

Token unexpected(void) {
  // omitted
}

Token next(void) {
  while (is_space(peek())) get();

  char c = peek();
  switch (peek()) {
    case '0':
    // omitted
    case '9':
      return number();
    default: 
      return unexpected();
  }
}

int main(int argc, char **argv) {
  printf(""); // works fine with this line

  input = argv[1];
  ptr = input;

  Token tokens[MAX_LEN];
  Token t;
  int i = 0;
  do {
    t = next();
    print_tok(t);
    
    tokens[i++] = t;

  } while (t.type != END && t.type != UNEXPECTED);

  return 0;
}

numberarr是一個局部變量。 局部變量在其函數結束時被銷毀,然后它的內容是不可預測的。 盡管如此,您的程序隨后會使用Token結構中的指針打印其值。

打印的值是不可預測的。 額外的printf("")語句可能會導致編譯器以一種不會覆蓋變量的方式重新排列代碼,或者類似的事情。 你不能依賴它。

您還有其他幾個選項可以為每個令牌分配內存:

  • 更改token str使其成為字符數組而不是指針。 然后每個令牌都有自己的空間來存儲字符串。
  • 使用malloc分配字符串。 然后它保持分配狀態,直到您free它。
  • main創建數組,使其對nextprint_tok都有效。 你必須給next一個指向數組的指針,這樣它就知道應該在哪里存儲字符串。 這一次只會存儲一個令牌的字符串。
  • 除了next使其成為局部變量之外,基本上任何其他創建數組的方式。
  • 使指針指向標記在原始字符串中的位置。 Token添加另一個變量來存儲令牌的長​​度。

我認為第一個選項最簡單,最后一個選項使用最少的內存,但為了完整性,我包含了一些其他選項。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM