0 votes

Inverser chaque caractère dans un fichier

Je suis un peu dans le pétrin ici.

Est-ce que quelqu'un peut m'aider à mettre en œuvre une solution qui inverse chaque octet afin que 0xAB devienne 0xBA mais pas que "abcd" devienne "dcba". J'ai besoin que AB CD EF devienne BA DC FE.

De préférence en C ou C++ mais cela n'a pas vraiment d'importance du moment que cela fonctionne.

Jusqu'à présent, j'ai mis en œuvre une solution VRAIMENT POURRIE qui ne fonctionne même pas (et oui, je sais que convertir en chaîne et reconvertir en binaire est une solution pourrie) en PureBasic.

OpenConsole()
filename$ = OpenFileRequester("Open File","","All types | *.*",0)
If filename$ = ""
End
EndIf
OpenFile(0,filename$)
*Byte = AllocateMemory(1)
ProcessedBytes = 0
Loc=Loc(0)
Repeat
FileSeek(0,Loc(0)+1)
PokeB(*Byte,ReadByte(0))
BitStr$ = RSet(Bin(Asc(PeekS(*Byte))),16,"0")
FirstStr$ = Left(BitStr$,8)
SecondStr$ = Right(BitStr$,8)
BitStr$ = SecondStr$ + FirstStr$
Bit.b = Val(BitStr$)
WriteByte(0,Bit)
ProcessedBytes = ProcessedBytes + 1
ClearConsole()
Print("Processed Bytes: ")
Print(Str(ProcessedBytes))
Loc=Loc(0)
Until Loc = Lof(0)
Delay(10000)

Merci d'avoir lu.

8voto

Lecture de votre code PureBasic (que j'ai ignoré au début), il semble que vous voulez échanger les octets, même si ce n'est pas ce que votre texte demande—0xAB signifie pratiquement toujours un octet de valeur décimale 171, et non deux octets, et il est extrêmement courant d'afficher un octet sous forme de deux chiffres hexadécimaux, où vous utilisez A-F dans votre exemple.

#include 
int main() {
  using namespace std;
  for (char a; cin.get(a);) {
    char b;
    if (!cin.get(b)) {
      cout.put(a); // mieux vaut l'écrire que le perdre
      cerr << "Zut, l'entrée se termine par un octet impair, est-ce dans "
        "le bon format?\n";
      return 1;
    }
    cout.put(b);
    cout.put(a);
  }
  return 0;
}
// La version en C est une traduction simple du code original

import numpy
import sys
numpy.fromfile(sys.stdin, numpy.int16).byteswap(True).tofile(sys.stdout)

Réponse originale :

Je ne suis pas sûr de pourquoi vous voulez cela (cela ne convertit pas l'endianness, par exemple, si c'est ce que vous voulez), mais voici :

#include 
int main() {
  for (char c; (c == getchar()) != EOF;) {
    putchar((c & 0xF << 4) | ((int)c & 0xF0 >> 4));
  }
  return 0;
}

#include 
int main() {
  for (char c; std::cin.get(c);) {
    std::cout.put((c & 0xF << 4) | ((int)c & 0xF0 >> 4));
  }
  return 0;
}

import sys
for line in sys.stdin:
  sys.stdout.write("".join(
    chr((ord(c) & 0xF << 4) | (ord(c) & 0xF0 >> 4))
    for c in line
  ))

Toutes partent du principe que les traductions de texte ne se produisent pas (comme \n en \r\n et vice versa) ; vous devrez les modifier pour ouvrir les fichiers en mode binaire si c'est le cas. Elles lisent depuis stdin et écrivent sur stdout, si vous n'êtes pas familier avec cela, utilisez simplement programname < inputfile > outputfile pour les exécuter.

2voto

Kornel Kisielewicz Points 26556

Inverser la moitié haute et basse d'un octet est possible grâce à une formule arithmétique simple (en supposant que vous travaillez sur des octets non signés) :

inversé = (original % 16) * 16 + (original / 16);

0voto

Thomas Eding Points 8651

Une solution Haskell:

module ReverseBytes where

import qualified Data.ByteString as B
import Data.Bits
import Data.Word

-----------------------------------------------------------

main :: IO ()
main = B.getContents >>= B.putStr . B.map reverseByte

reverseByte :: Word8 -> Word8
reverseByte = flip rotate 4

runghc ReverseBytes.hs < inputfile > outputfile

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X