Вычесть массив символов минус int в C - PullRequest
0 голосов
/ 28 апреля 2020

У меня есть массив символов:

char message[];

И 8-битное целое число

uint8_t remainder

Я хочу трактовать оба элемента как массивы битов и вычитать их как:

message - remainder

и обработайте результат как массив символов:

Примером может быть

char* message = "ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ";
// Equivalent to a 512-bit array of only 1s

uint8_t remainder = 1;
// Substract here message-remainder

printf("%s", message)
// Output: "ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþ"
// As the 512 bit array would still be just 1s except for the first bit which now is 0, so the first char would be 254 instead of 255

Есть ли способ сделать это? Я думал о преобразовании массива char в int, но проблема в том, что он обычно представляет собой массив из 64 байтов, поэтому я не могу обработать его как int. Я думаю, что подход основан на использовании побитовых операторов, но я еще не понял, как их вычесть.

Есть предложения?

Ответы [ 2 ]

2 голосов
/ 28 апреля 2020

По запросу:

  1. Чтение из байтового массива (символов) как целочисленного типа. Помните, что в некоторых системах этот метод может работать некорректно, и вам, возможно, придется выполнить обмен endian. Также помните, что если данные не выровнены по границам слов, некоторые системы могут взломать sh.
  2. Сравните ваш остаток с целым числом. Если целое число> = остаток, нет переноса, и вы можете просто вычесть значения, и Typecast сохранить целое число обратно в массив символов. Применяются те же исключения, как указано выше.
  3. Если остаток больше, вычтите и сохраните, но затем поместите 1 в остаток.
  4. L oop обратно на 1, читая в следующем слово, пока вы не выйдете из-за отсутствия переноса для распространения или из слов для чтения.

Если данные не выровнены, не размер слова, и т. д. c., вам может потребоваться сделать это вместо байта, но вы заявили, что это не так.

Наслаждайтесь.

(Примечание. Использование библиотеки типов BigNum настоятельно рекомендуется, если вы делаете это самостоятельно. Когда-нибудь этот код может потребоваться быть портированным, и этот метод с большой вероятностью сломается, когда это произойдет ...)

1 голос
/ 29 апреля 2020

Во-первых, это, как правило, плохая идея :-( (обычно вызывает некоторое переполнение буфера)

Во-вторых, поскольку интересующее вас целое число является 8-разрядным, оно того же размера, что и single char. Поэтому, если вы хотите реализовать это, просто сделайте следующее:

if (message[strlen(message)-1]<integer){
    for (int i=strlen(message);i>0;i--){
        if (message[i-1]){
            message[i-1]--;
            for (j=i+1;j<strlen(message)-1;j++){
                message[j]=255;
            }
            message[strlen(message)-1]=(char)((int)(message[strlen(message)-1])+255-remainder);
            break;
        }
    }
    /* ERROR - message is less than remainder */
}
else{
    message[strlen(message)-1]-=remainder;
}

и все готово.

Обратите внимание, что деталь (char)((int)(message[strlen(message)-1])+255-remainder) может не понадобиться; Я пишу это просто, чтобы убедиться, что при выполнении сложения и вычитания все преобразуется в int.

...