1

Raspberry pi で結果を送信する外部マシンがあります。私のエミュレータである Cutecom では、行ごとに問題なく結果が得られます。私は Codeblocks を使用し、これらのデータを 10 秒ごとに読み取る独自の C アプリケーションを作成しました。しかし、奇妙なことが起こります。行ごとに結果が表示されることもあれば、各行の最後に奇妙な文字 ^M ^J が表示されることもあり、その結果、ひどい最終結果が得られます。これらの EOF 文字は、外部マシンが Windows で開発されたためだと思います。

良い結果

+PARAMETERS: 45 BYTES FROM 0000:0000 (063)
MACHINE_1:(AN=23.45,H=34.56,D=12.34)

悪い結果

+PARAMETERS: 45 BYTES FROM 0000:0000 (063)^M^JMACHINE_1:
(AN=21.45,H=33.56,D=10.34)

わかりました、ここまで唯一の問題はコマンドラインが結果を表示する方法ですが、私の結果は問題ありません。しかし、strtok を使用していくつかのトークンを取得しようとすると、これらの文字が原因で深刻な問題が発生します。私に何ができる?これらの文字をエスケープするために何かを追加できますか?これは、マシンからデータを読み取るために使用するコードの一部です

char buff[300];
memset(buff, 0, sizeof(buff));
for (;;)
{
  n=read(fd,buff,sizeof(buff));
  sleep(1);
  printf("%s", buff);
  printf("\n");
  ....
  ....
4

3 に答える 3

1

300 文字のブロックを読み取っているだけなので、文字列の終端はありません\0

読み取ったデータの量を確認し、印刷する前にデータを処理する必要がありますn。つまり、行を探して^J^M終了し、残りのデータの読み取りを続けます。

参考^J^Mまでに、Windows の回線終端です ( ^JLinux の形式です)。

以下は、複数のメッセージを読み取り、^ と J を \n に変換し、^M を無視する必要があります。

これは、シリアルポートではなく、STDIN を使用することに注意してください。

#include <stdio.h>
#include <unistd.h>

int main(int argc, char** argv)
{
    int fd=STDIN_FILENO;
    int i,n;
    int c=0;

    char buff[300];
    memset(buff, 0, sizeof(buff));
    for (;;)
    {
        n=read(fd,buff,sizeof(buff));
        for (i=0; i<n; i++) 
        {
            switch(buff[i])
            {
            case '^':
                if(c) 
                {
                    // ^^ so output first ^
                    putchar('^');
                }
                else
                {
                    // Possible ^M or ^J
                    c++;
                }
                break;

            case 'M':
                if (c)
                {
                    // ignore ^M
                    c=0;
                }
                else
                {
                    // just M 
                    putchar(buff[i]);
                }
                break;

            case 'J':
                if (c)
                {
                    // ^J is \n
                    putchar('\n');
                    c=0;
                }
                else 
                {
                    // just J
                    putchar(buff[i]);
                }
                break;

            default:
                if (c)
                {
                    // ^ followed by other than J or M
                    putchar('^');
                    c=0;
                }

                putchar(buff[i]);
            }
        }

    }
    return 0;
}
于 2013-06-07T07:07:25.917 に答える
0

これでまだまだ使えると思いますstrtok()。パラメータに^Mand^Jを追加するだけです。char *delimiters

于 2013-06-07T07:12:45.087 に答える
0

コマンド「sed -e 's/\^\M$//g' filename」を実行するだけです。

または私はこれをウェブサイトから入手しました。

#!/usr/bin/python
while True:
  file = raw_input('Input file name:(input "q" to quit)')
  if file == 'q':
      break
  file_ = open(file).read()
  list_ = list(file_)
  new_file = ''
  for x in list_:
      if x != '^' and x != 'M':
          new_file = new_file + x
  file_ = open(file,'w')
  file_.write(new_file)
  file_.close()
于 2013-06-07T07:38:54.533 に答える