0

I have been working on creating a coreutils style C program that does a Cesar shift cipher on a given input. Here is the link to the repository. Right now, the program only reads a specified file and shifts each character before printing it. I am wanting to add the ability to pipe input through my program like you would see in the wc command.

$ echo "pants" | ccipher --key 7
whuaz

When an encryption key is specified, 1-26, handling piped input would be trivial. Each character would be gathered with getchar(), shifted by the key and putchar() would print it to stdout.

In my program though, when a key isn't specified it loops through the input with keys 1-26 and prints to stdout.

$ cat input
pants
$ ccipher input
qbout
rcpvu
sdqwv
terxw
ufsyx
vgtzy
whuaz
xivba
yjwcb
zkxdc
alyed
bmzfe
cnagf
dobhg
epcih
fqdji
grekj
hsflk
itgml
juhnm
kvion
lwjpo
mxkqp
nylrq
ozmsr

This is easy with a file. In a file, the c program loops through the input file and calls rewind() after each iteration of the loop.

void allKeys(FILE** file) {
  long key;
  char c;
  for (key = 1; key < 26; key++) {
    while ((c = fgetc(*file)) != EOF) {
      rotateChar((char)c, key);
    }
    rewind(*file);
  }
  fclose(*file);
}

The problem that I am having is something that the wc utility wouldn't have to deal with. That is storing input from stdin for the subsequent times the input needs to be ran through.

I have came across a couple solutions that people said to use when storing input temporarily. The first was having a dynamic buffer that is resized whenever it is filled up. This seems great, but with the drawback being how the program could be cat'd a file larger than the amount of available ram and take up all of the system resources.

The second solution that I came across was temp files. With a temp file, the program would store the input in a temp file and be able to rewind it like any other file.

My goal with this stack overflow question was to see if there are any other and potentially better ways to solve this problem. If not, which one of the solutions I have listed should I use?

5
  • 1
    You can't seek in a pipe, so you have to store the contents somewhere. There isn't really any other choice besides a memory buffer or a file. Commented Jan 19, 2024 at 18:32
  • 2
    It's a problem that GNU sort has to deal with, and it does it by storing in memory up to a point, then spilling to files. Commented Jan 19, 2024 at 18:32
  • @thatotherguy I think that will be how I do it. I'll start reading sort's source code for the specifics. Commented Jan 20, 2024 at 2:44
  • Side note: You don't need a "double star" pointer (e.g. FILE **) in the function. You can do the same with just a FILE * Commented Jan 20, 2024 at 3:01
  • @CraigEstey I just added that to the repo thanks for pointing that out. Commented Jan 20, 2024 at 4:24

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.