views:

1934

answers:

6

To start off, I'm four weeks into a C++ course and I don't even know loops yet, so please speak baby talk?

Okay, so I'm supposed to read a twelve character string (plus NULL makes thirteen) from a file, and then shift the letters backwards three, and then print my results to screen and file. I'm okay with everything except the shifting letters. I don't want to write miles of code to take each character individually, subtract three, and re-assemble the string, but I'm not sure how to work with the whole string at once. Can someone recommend a really simple method of doing this?

+1  A: 

Iterate over the characters with a for loop. And do what you want with the char*. Then put the new char back.

IceHeat
+1  A: 
for(int i=0; i<12; i++){
  string[i] = string[i] - 3;
}

Where string is your character array (string). There is a bit more involved if you want to make it periodic (I.E. have A wrap round to Z, but the above code should help you get started)

Jamie Lewis
+2  A: 

You're going to have to learn loops. They will allow you to repeat some code over the characters of a string, which is exactly what you need here. You'll keep an integer variable that will be your index into the string, and inside the loop do your letter-shifting on the character at that index and increment the index variable by one until you reach NULL.

Edit: If you're not expected to know about loops yet in your course, maybe they want you to do this:

string[0] -= 3; // this is short for "string[0] = string[0] - 3;"
string[1] -= 3;
string[2] -= 3;
...

It will only result in 12 lines of code rather than miles. You don't have to "reassemble" the string this way, you can just edit each character in-place. Then I bet after making you do that, they'll show you the fast way of doing it using loops.

yjerem
+1  A: 

I'm a little unclear what you mean by "shift the letters backwards 3"? Does that mean D ==> A?
If so, here's a simple loop.

(I didn't do reading from the file, or writing to the file... Thats your part)

#include <string.h>

int main(void)
{                      
    char input[13] = "ABCDEFGHIJKL";
    int i;

    int len = strlen(input);

    for(i=0; i<len; ++i)
    {
     input[i] = input[i]-3;
    }

    printf("%s", input);  // OUTPUT is: ">?@ABCDEFGHI"
}
abelenky
WTF is the down-vote for? I think my answer is pretty clear and straightforward.
abelenky
I didn't downvote you, but my guess would be it's because you provided code rather than explaining *how* to solve the problem, which isn't so beneficial to somebody just beginning to learn.
Chuck
+5  A: 

If you are dealing with simple letters (A to Z or a to z), then you can assume that the internals codes are linear.

Letters are coded as numbers, between 0 and 127. A is coded as 65, B as 66, C as 67, Z as 90.

In order to shift letters, you just have to change the internal letter code as if it were a number, so basically just substracting 3 from the character. Beware of edge cases though, because substracting 3 to 'A' will give you '>' (code 62) and not 'X' (code 88). You can deal with them using "if" statements or the modulo operator ("%").

Here is an ASCII characters table to help you

Vincent Robert
+3  A: 

Once you've loaded your string in, you can use the modulous operator to rotate while keeping within the confines of A-Z space.

I'd keep track of whether the letter was a capital to start with:

bool isCaps = ( letter >= 'A' ) && ( letter <= 'Z' );
if( isCaps )
  letter -= 'A'-'a';

and then just do the cipher shift like this:

int shift = -3;
letter -= 'a'; // to make it a number from 0-25
letter = ( letter + shift + 26 ) % 26;
        // add 26 in case the shift is negative
letter += 'a'; // back to ascii code

finally finish off with

if( isCaps )
  letter += 'A'-'a';

so, putting all this together we get:

char *mystring; // ciphertext
int shift = -3; // ciphershift

for( char *letter = mystring; letter; ++letter )
{
  bool isCaps = ( *letter >= 'A' ) && ( *letter <= 'Z' );
  if( isCaps )
    *letter -= 'A'-'a';

  letter -= 'a';
  letter = ( letter + shift + 26 ) % 26;
  letter += 'a';

  if( isCaps )
    letter += 'A'-'a';
}
Richard Fabian