0

以下は、トークンの解析に使用するコードのセクションです。

>>>>一番下に で示されている不要になった行がありますが、コメントアウトするとcmd_parse_value_lookup()関数が失敗します。そのままにしておくと、コードは正しく実行されます。誰かが理由を教えて、何が起こっているのか説明してもらえますか?

void cmd_parse(void)
  {
    cmd_parse_value=0;  
    int cmd_parse_counter = 1;
    char *cmd_parse_pointer;
    cmd_parse_pointer = strtok(cmd_buffer_in, " ");
    if (cmd_parse_pointer!=NULL)
    {
      cmd_parse_value_lookup(cmd_parse_pointer);
    }
    while (cmd_parse_pointer != NULL)
    {
      cmd_parse_counter++;
      cmd_parse_pointer = strtok(NULL, " ");
      if (cmd_parse_pointer!=NULL)
      {
   >>>>cmd_buffer_sprintf_return = sprintf(cmd_buffer_sprintf,"%i: %s\r\n", cmd_parse_counter, cmd_parse_pointer);  //WHY DO I NEED THIS LINE
        cmd_parse_value_lookup(cmd_parse_pointer);
      }
    }
  }

void cmd_parse_value_lookup(char *cmd_command)
{
  if (strcmp(cmd_command,"show")==0)
  {
    cmd_parse_value |= 1;
  }
  else if (strcmp(cmd_command,"get")==0)
  {
    cmd_parse_value |= 1;
  } 
  else if (strcmp(cmd_command,"set")==0)
  {
    cmd_parse_value |= 2;
  }
  else if (strcmp(cmd_command,"system")==0)
  {
    cmd_parse_value |= 4;
  }
}

編集:これは完全なコードです:

/** C O M M A N D ************************************************************/

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

void btm_out_character (char character);
void btm_out_string(char *string);
void cmd_parse(void);

char cmd_buffer_in[81]="\0                                                                         ";
int cmd_buffer_in_position=0;
unsigned long long cmd_parse_value=0;

char cmd_buffer_sprintf[81];
int cmd_buffer_sprintf_return;

void cmd_parse_value_lookup(char *cmd_command);
void cmd_buffer_in_add(int character);

void cmd_init(void)
{

}

void cmd_cls(void)
{
    if (dbg_mode==1){btm_out_string("\033[2J\033[1;33;40m\033[H\r\n");}
    if (dbg_mode==1){btm_out_string("================================================================================");}
    if (dbg_mode==1){btm_out_string("\033[24;0H================================================================================");}
    if (dbg_mode==1){btm_out_string("\033[1;36;40m\033[8;66H DEBUG MODE ");}
    if (dbg_mode==1){btm_out_string("\033[24;7H ***** ******** ********** Engineering Limited, All Rights Reserved ");}
    if (dbg_mode==1){btm_out_string("\033[10;0H");}
}   

void cmd_prompt(void)
{
    cmd_buffer_in_position = 0; // Clear buffer position
    cmd_buffer_in[0]=0;  // Clear buffer
    if (dbg_mode==1){btm_out_string("\r\n\033[1;37;40m***:> ");}    
}

void cmd_buffer_in_add(int character)
{
    switch (character)
    {
        case 8:
            if (cmd_buffer_in_position>0)
            {
                if (dbg_mode==1){btm_out_string("\b \b");}
                cmd_buffer_in[(int)cmd_buffer_in_position-1] = (char)character;
                cmd_buffer_in[(int)cmd_buffer_in_position] = 0;
                cmd_buffer_in_position--;
            }
                else
            {
                if (dbg_mode==1){btm_out_character(7);}     //BELL alert (too long a string)
                cmd_buffer_in[0] = 0;
                cmd_buffer_in_position = 0;
            }
            break;
        case 13:
            cmd_parse();
            cmd_buffer_sprintf_return = sprintf(cmd_buffer_sprintf,"\r\nparse value=%llu\r\n", cmd_parse_value);
            if (dbg_mode==1){btm_out_string(cmd_buffer_sprintf);}
            cmd_prompt();
            break;
        default:
            if (cmd_buffer_in_position<73)
            {
                if (dbg_mode==1){btm_out_character((char)character);}       //Echo character to host
                cmd_buffer_in[(int)cmd_buffer_in_position] = (char)character;
                cmd_buffer_in[(int)cmd_buffer_in_position+1] = 0;
                cmd_buffer_in_position++;
            }
            else
            {
                if (dbg_mode==1){btm_out_character(7);}     //BELL alert (too long a string)
            }
    }//switch
}//cmd_buffer_in_add

void cmd_parse(void)
{
    cmd_parse_value=0;

    /* this was code for testing */
    //cmd_buffer_sprintf_return = sprintf(cmd_buffer_sprintf,"\r\nClone %s",cmd_buffer_in);
    //cmd_buffer_sprintf_return = sprintf(cmd_buffer_sprintf,"Returnval='%i''%i''%i'",cmd_buffer_in[(int)0],cmd_buffer_in[(int)1],cmd_buffer_in[(int)2]);
    //if (dbg_mode==1){btm_out_string(cmd_buffer_sprintf);}

    int cmd_parse_counter = 1;
  char *cmd_parse_pointer;

  cmd_parse_pointer = strtok(cmd_buffer_in, " ");
  if (cmd_parse_pointer!=NULL)
    {
    cmd_parse_value_lookup(cmd_parse_pointer);
  }
  while (cmd_parse_pointer != NULL)
  {
      cmd_parse_counter++;
    cmd_parse_pointer = strtok(NULL, " ");
    if (cmd_parse_pointer!=NULL)
    {
        cmd_buffer_sprintf_return = sprintf(cmd_buffer_sprintf,"%i: %s\r\n", cmd_parse_counter, cmd_parse_pointer);  //WHY DO I NEED THIS LINE
            //if (dbg_mode==1){btm_out_string(cmd_buffer_sprintf);}
            cmd_parse_value_lookup(cmd_parse_pointer);
    }
  }
}

void cmd_parse_value_lookup(char *cmd_command)
{
    if (strcmp(cmd_command,"show")==0)
    {
        cmd_parse_value |= 1;
    }
    else if (strcmp(cmd_command,"get")==0)
    {
        cmd_parse_value |= 1;
    } 
    else if (strcmp(cmd_command,"set")==0)
    {
        cmd_parse_value |= 2;
    }
    else if (strcmp(cmd_command,"system")==0)
    {
        cmd_parse_value |= 4;
    }
    else if (strcmp(cmd_command,"sys")==0)
    {
        cmd_parse_value |= 4;
    }
    else if (strcmp(cmd_command,"adc")==0)
    {
        cmd_parse_value |= 8;
    }
    else if (strcmp(cmd_command,"a2d")==0)
    {
        cmd_parse_value |= 8;
    }
    else if (strcmp(cmd_command,"channel1")==0)//
    {
        cmd_parse_value |= 16;
    }
    else if (strcmp(cmd_command,"ch1")==0)
    {
        cmd_parse_value |= 16;
    }
}
4

4 に答える 4

0

他の場所では使用しないためcmd_buffer_sprintf、そのコード行は役に立たないようです。他の場所で使用するグローバル変数の場合も cmd_buffer_sprintfありますが、提示したコードでは、その行は何も変更しません。

于 2012-08-13T22:13:03.587 に答える
0

反対票をくれた人は誰でも、C を学んでいたとしても、この問題の原因となったコンパイラのバグがあるとすぐに推測したはずです。

とにかく、問題への答えは、コンパイラが unsigned long long を大ざっぱに (せいぜい) サポートしているということでした。何らかの理由で、その行は機能します。unsigned long long の使用を避けるセクションを書き直したので、すべてがソートされました。これを解決しようとするあなたのサポートに感謝します。

于 2012-08-13T23:55:40.930 に答える
0

コメントしようとしている行で使用されている var cmd_parse_counter は、行をコメントアウトすると役に立たなくなることがわかります。

コンパイラの論理的な動作は、アセンブリ コードからそれを削除することです。

これにより、コード内の別の場所で発生しているバッファ オーバーフローまたはスタック エラーが修正される可能性があります。

この理論をテストするには、cmd_parse_counter を volatile int cmd_parse_counter として宣言し、その行をコメントアウトして、コードが実行されるかどうかを確認します。実行される場合は、さらに進んで問題を見つけることができます。あなたが見つけたように、それはあなたの長さに関連しているかもしれません.

確認すべきもう 1 つのことは、バッファーをスペースで埋めてから、スペース トークンを使用して分割していることです。分割するたびに、strcmp を実行します。バッファが 0 で終わらない場合、0 文字なしで strcmp を使用すると確実にクラッシュします。for ループを使用して、バッファをすべて 0 で初期化することができます。

于 2014-01-03T14:28:49.843 に答える
0

cmd_buffer_sprintfその行を取り出すと、初期化されていない可能性があります。

*cmd_buffer_sprintf = '\0'どこかにを追加してみてmain()、問題が解決するかどうかを確認してください。

于 2012-08-13T22:23:44.380 に答える