2012-06-06 2 views
12

부품 바이너리 및 ASCII 부분 인 GPS로부터 수신 한 데이터를 저장하기 위해 QByteArray이 있습니다. 나는 수신되고 있는지 알고 디버그 제안에 대해 알고 싶은, 그래서 나는 이런 qDebug을 쓰고 있어요 :qDebug가 바이너리 데이터가 포함 된 전체 QByteArray를 인쇄하지 않습니다.

//QByteArray buffer; 
//... 
qDebug() << "GNSS msg (" << buffer.size() << "): " << buffer; 

그리고 콘솔에 다음과 같은 메시지를 얻을 :

GNSS msg (1774): "ygnnsdgk...(many data)..PR085hlHJGOLH 
(more data into a new line, which is OK because it is a new GNSS sentence and 
probably has a \n at the end of each one) blablabla... 

그러나 갑자기 내가 얻을 새로운 인쇄 반복. 데이터가 아직 지워지지 않았으므로 추가되었습니다. 예를 들어 3204와 같이 새 메시지 크기가 이전 인쇄보다 큽니다. 그러나 똑같은 내용을 인쇄합니다 (괄호 사이에 새 크기 3204가 표시됨).

GNSS msg (3204): "ygnnsdgk...(many data)..PR085hlHJGOLH 
(more data into a new line, which is OK because it is a new GNSS sentence and 
probably has a \n at the end of each one) blablabla... 

가 나는 그것이 한계가 있기 때문에, 또는 그것이 종료 문자 또는 그런 일에 도달하기 때문에 qDebug가 인쇄를 중단 생각하지만, 나는 단지 해요 : 어떤 새로운 데이터가 이전 메시지처럼 같은 인쇄되지 않는 것은 있었다 추측.

이 동작에 대한 도움이나 의견이 있으십니까?

답변

23

솔루션/해결 방법 : 실제로

, QByteArrayqDebug() 출력이 '\0' 문자에서 잘립니다. 이것은 QByteArray와 관련이 없습니다. qDebug()를 사용하여 '\ 0'문자를 출력 할 수도 없다. 설명은 아래를 참조하십시오.

QByteArray buffer; 
buffer.append("hello"); 
buffer.append('\0'); 
buffer.append("world"); 

qDebug() << "GNSS msg (" << buffer.size() << "): " << buffer; 

출력 : 심지어 어떤 다음 인수는 무시됩니다

GNSS msg (11): "hello 

:

qDebug() << "hello" << '\0' << "world"; 

출력 :

hello 

당신은 대체하여이 "문제"를 해결할 수 있습니다 바이트의 특수 문자 를 디버깅하기 전에 배열 :

QByteArray dbg = buffer; // create a copy to not alter the buffer itself 
dbg.replace('\\', "\\\\"); // escape the backslash itself 
dbg.replace('\0', "\\0"); // get rid of 0 characters 
dbg.replace('"', "\\\""); // more special characters as you like 

qDebug() << "GNSS msg (" << buffer.size() << "): " << dbg; // not dbg.size()! 

출력 :

GNSS msg (11): "hello\0world" 

왜 이런 일이? qDebug()를 사용하여 '\0'을 출력 할 수없는 이유는 무엇입니까?

무엇이 qDebug()인지 알아 보려면 Qt 내부 코드를 살펴 보겠습니다. 다음 코드 단편은 Qt 4.8.0 소스 코드에서 발췌 한 것입니다.

당신이 qDebug() << buffer을 수행 할 때이 메소드가 호출된다

inline QDebug &operator<<(const QByteArray & t) { 
    stream->ts << '\"' << t << '\"'; return maybeSpace(); 
} 

stream->ts은 위의 QStringQByteArray 변환 형 QTextStream,이다 :

QTextStream &QTextStream::operator<<(const QByteArray &array) 
{ 
    Q_D(QTextStream); 
    CHECK_VALID_STREAM(*this); 
    // Here, Qt constructs a QString from the binary data. Until now, 
    // the '\0' and following data is still captured. 
    d->putString(QString::fromAscii(array.constData(), array.length())); 
    return *this; 
} 

당신이 볼 수 있듯이, d->putString(QString) (d의 형식은 텍스트 스트림의 내부 전용 클래스입니다.)를 호출합니다.상수 너비 필드에 대해 일부 패딩을 수행 한 후 나는 putString(QString)의 코드를 생략하고 직접 다음과 같이 정의된다 d->write(QString)로 이동 : 당신이 볼 수 있듯이

inline void QTextStreamPrivate::write(const QString &data) 
{ 
    if (string) { 
     string->append(data); 
    } else { 
     writeBuffer += data; 
     if (writeBuffer.size() > QTEXTSTREAM_BUFFERSIZE) 
      flushWriteBuffer(); 
    } 
} 

QTextStreamPrivate는 버퍼를 가지고있다. 이 버퍼의 유형은 QString입니다. 최종적으로 버퍼가 터미널에 인쇄되면 어떻게 될까요? 이를 위해 qDebug() 문이 끝나고 버퍼가 메시지 처리기로 전달 될 때 어떤 일이 발생하는지 알아야합니다. 기본적으로 메시지 처리기는 터미널에서 버퍼를 인쇄합니다. 그래서 여기

inline ~QDebug() { 
    if (!--stream->ref) { 
     if(stream->message_output) { 
     QT_TRY { 
      qt_message_output(stream->type, stream->buffer.toLocal8Bit().data()); 
     } QT_CATCH(std::bad_alloc&) { /* We're out of memory - give up. */ } 
     } 
     delete stream; 
    } 
} 

을 비 바이너리 안전 부분이 다음과 같이 정의된다 QDebug 클래스의 소멸자에서 일어나고있다. Qt는 텍스트 버퍼를 "로컬 8 비트"바이너리 표현으로 변환합니다 (지금까지 AFAIK는 우리가 디버깅 할 바이너리 데이터를 가지고 있어야합니다).

그러나 이진 데이터 길이가 추가 지정되지 않은 메시지 처리기에 전달합니다. 아시다시피, C 문자열의 길이를 알아내는 것은 불가능합니다. '\0' 문자도 포함 할 수 있어야합니다. (위의 코드에서 QString::fromAscii()이 이진 안전을 위해 추가 길이 매개 변수가 필요한 이유입니다.) 문자를 처리하려는 경우 자체 메시지 처리기를 작성해도 문제가 해결되지 않습니다. 길이를 알아라. 슬프지만 사실이야.

+0

"문제"라는 단어를 인용하지 않겠지 만 실제로 버그가있는 것 같습니다 (qDebug가 정상적으로 추가 한 문자열 뒤에 누락 된 "닫기"로 입증 됨). –

+0

@fish 나는 또한 데이터를 " \ 0'' 좋은 아니에요. 다른 측면에서, 나는 qDebug 출력 (적어도 QString 및 QByteArray)에 대한 텍스트 데이터를 만든 것 같아요. 하나는 QByteArray의 경우,이 * 안된다고 주장 할 수 있습니다 * 그러나 Qt가 어떻게 바이너리 데이터를 디버깅하길 원하는지 모르겠다 고 주장 할 수 있습니다 .0 문자를 출력해도 작동하지만 하나도 읽을 수 없습니다 (qDebug()의 목적입니다). 아마도 .toHex() 어떤 경우에는 바이너리 데이터를위한 더 나은 솔루션입니다. 그래서 Qt는 데이터를 출력하는 방법을 여러분에게 맡깁니다. – leemes

+0

그렇지만 이것이 올바른 행동이라고 주장 할 수 있습니다. 그것은 의도하지 않았고 그렇지 않은 경우 추가 누락 ". –

관련 문제