Вопрос о том, почему строка обрезается в первом экземпляре \ 0 - PullRequest
2 голосов
/ 12 января 2010

У меня есть функция, которая читает символ, по одному байту за раз, через последовательный порт. После того, как эти байты собраны, они передаются методу для обработки байтов и сообщения.

Я знаю, как решить проблему (исправление приведено ниже), но почему мои байты усекаются, когда я не выполняю исправление?

unsigned char dpBuf[255];
...

// Pretend dpBuf has values 0x01 0x02 0x03 0x00 0x00 0x00 0x04 0x05
..
ProcessMsg(dpBuf);
..
void ProcessMsg(unsigned char *buff)
{
    // buff comes in as 0x01 0x02 0x03 0x00 and rest is truncated
    char p[255];
    ...
    for (int i = 0; i < sizeof(buff); i++) 
    {
        sprintf(p, " 0x%X ", (unsigned char)b[i]);
    }
    ..
}

Fix:

ProcessMsg((unsigned char*)&dpBuf, length); // instead of sizeof() in the loop, use length

..

void ProcessMsg (unsigned char *buff, int length)
{
    // buff comes in as the original character string and is not truncated
    .. 
    // do for loop, print out contents

}

Ответы [ 6 ]

11 голосов
/ 12 января 2010

buff объявлен как const char*, поэтому sizeof(buff) возвращает размер такого указателя, который на вашем компьютере составляет 4 байта. Поэтому первые четыре байта буфера затем печатаются в цикле.

Неважно, что dpBuf объявлен как массив большего размера, потому что он передается функции как указатель. Чтобы обойти эту проблему, вы должны добавить параметр в функцию, где размер буфера передается явно.

3 голосов
/ 12 января 2010

buff - указатель, следовательно, его размер равен 4. sizeof (buff) = 4 sizeof (dpBuf) = 255

Вы хотели второй.

2 голосов
/ 12 января 2010

Как все уже говорили, в C ++ массив символов с нулевым символом в конце называется строкой. Размер буфера, в котором хранятся символы, может быть больше, чем «длина строки» в этих терминах. Например:

char inBuf [] = {0x01, 0x02, 0x03, 0x00, 0x00, 0x04, 0x05};
size_t bufSize = sizeof(inBuf);
size_t rawLen = strlen(inBuf);

... в этом случае размер inBuf равен 7, но strlen () возвращает 3.

Используя ASCII, вы не можете вставлять NULL в строку. Тем не менее, вы можете использовать std :: string, если хотите встраивать NULL. std :: string обычно полезен в любом случае, так что проверьте это. Полный рабочий пример:

#include <cstdlib>

#include <string>
#include <iostream>
using namespace std;

char inBuf [] = {0x01, 0x02, 0x03, 0x00, 0x00, 0x04, 0x05};

int main()
{
    size_t bufSize = sizeof(inBuf);
    size_t rawLen = strlen(inBuf);
    string ss(inBuf, sizeof(inBuf));
    size_t ssLen = ss.length();

    cout << "Buffer Size = " << bufSize << ", Raw string length = " << rawLen << ", std::string length = " << ssLen;

    return 0;

}

Вывод программы:

Размер буфера = 7, длина необработанной строки = 3, std :: длина строки = 7

1 голос
/ 12 января 2010

Sizeof (buff) возвращает размер const char *, потому что это тип баффа. Я думаю, что вы искали метод strlen (бафф), но даже тогда strlen остановится, когда найдет нулевой терминатор. http://www.cplusplus.com/reference/clibrary/cstring/strlen/

В стандарте ascii 0x00 считается нулевым терминатором, который обычно считается концом строки стиля c.

Я бы посоветовал вам взглянуть и на строки stl. http://www.cplusplus.com/reference/string/string/

1 голос
/ 12 января 2010

sizeof (buff) запрашивает размер указателя - вероятно, 4

1 голос
/ 12 января 2010

Ваш код неверен: for (int i = 0; i < sizeof(buff); i++)

Используется sizeof, что фактически эквивалентно вызову sizeof(unsigned char*). Вы должны передать длину явно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...