2016-12-14 7 views
1

EDIT: После выполнения еще нескольких исследований кажется, что мне действительно нужен большой конец от среднего до среднего и наоборот. поэтому 12345678 -> 34127856 и обратно. Извините за любую путаницу.C: Чтение всего файла в буфер и byteswap buf | ADDECEFA -> DEADFACE

У меня есть небольшой файл, ровно 16 МБ. Я читаю весь файл в буфер. То, что я пытаюсь сделать, это byteswap весь файл/буфер за один раз, если это возможно (например, унифицированные/глобальные свопы ADDECEFA => DEADFACE). Я прочитал бесчисленные страницы с байтами, но многие из поразрядных/байтовых файлов по какой-то причине попадают прямо мне в голову (скорее всего, немой мозг). Если кто-то знает побитовое/byteswap для чайников, пожалуйста, укажите мне в правильном направлении!

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

int main(int argc, char *argv[]) 
{ 

    const char * suffix = ".reversed"; 

    FILE *input = fopen(argv[1], "rb"); 
    char * out = strcat(argv[1], suffix); 
    FILE *output = fopen(out, "wb"); 

    int data[16384]; 
    int swapped; 

while(fread(data,sizeof data, 1, input)){ 

    swapped = ((data & 0x000000FF) << 24) | 
       ((data & 0x0000FF00) << 8) | 
       ((data & 0x00FF0000) >> 8) | 
       ((data & 0xFF000000) >> 24); 

    fwrite(swapped, sizeof data , 1, output); 

      /* by golly it copies the file fast as heck! 
       but i am unsure how to manipulate 'data' buffer 
       so as it uniformly/globaly swaps ADDECEFA => DEADFACE 
      */ 
     } 
    } 

Кроме того, если вы видите, что я делаю что-то не так в своем коде, расскажите мне и покажите мне лучший способ. Если вам нужно, чтобы я что-то уточнял, не стесняйтесь спрашивать. Спасибо и хорошо.

EDIT: Я добавил одну из моих неудачных попыток. Моя конечная цель состояла в том, чтобы поменять байты, когда я напишу обратно в outfile и поменяю их как можно более эффективно.

+0

Это слишком опасно для 'strcat (argv [1], suffix),' вы понятия не имеете, достаточно ли места. –

+0

Хмм, а как лучше всего справиться с этим? Я искал способ добавить суффикс к имени файла из argv. outcourse argv [1] + ". suffix" didnt work; ( – james28909

+0

Я предполагаю, что могу вывести статическое имя файла, а затем переименовать его после выполнения im. – james28909

ответ

1

Учитывая

int data[16384]; 

этот код

while(fread(data,sizeof data, 1, input)){ 

будет пытаться читать 16384 int значения из input. Пока ничего плохого.

Но этот код:

swapped = ((data & 0x000000FF) << 24) | 
      ((data & 0x0000FF00) << 8) | 
      ((data & 0x00FF0000) >> 8) | 
      ((data & 0xFF000000) >> 24); 

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

Вы, вероятно, хотите что-то вроде этого:

swapped = ((data[ 0 ] & 0x000000FF) << 24) | 
      ((data[ 0 ] & 0x0000FF00) << 8) | 
      ((data[ 0 ] & 0x00FF0000) >> 8) | 
      ((data[ 0 ] & 0xFF000000) >> 24); 

Но есть проблема, что переход подписаннойint значения имеет определенную реализацию поведения. См Arithmetic bit-shift on a signed integer

Таким образом, вы, вероятно, хотите

unsigned int data[16384]; 

Даже если учесть, что, хотя, вы только замена одного int значение. Вам нужно перебрать все прочитанные данные, обменяв каждый int, предполагая, что это то, что вы хотите сделать.

Что вызывает другую проблему - ваш код не отслеживает, сколько данных ему нужно для обмена байтами. Вам нужно подсчитать количество значений int, считанных в и использовать это.

Наконец, этот код

fwrite(swapped, sizeof data , 1, output); 

запишет sizeof data байт output, начиная с адреса из любой swapped случается, чтобы указать.Но это определение swapped:

int swapped; 

Так что fwrite() вызов неопределенное поведение.

+0

«Но это определение обменивается» хм, я думал, что добавил к замене, когда пытался использовать данные с байтами. Я думаю, что я понимаю, что вы имеете в виду, хотя я должен был правильно «изменить размер»? – james28909

+1

@ james28909 - предполагая, что вы имеете в виду оператор 'fwrite()', вероятно, это должно быть что-то вроде 'fwrite (& swapped, sizeof swapped, 1, output);' Обратите внимание, что первым аргументом 'fwrite()' является * адрес * данных, которые нужно записать. –

+0

Я ценю ваши комментарии, поэтому спасибо за это. но я собираюсь положить это на вечер и забрать его завтра. Спасибо за вашу помощь – james28909