0

I’ve successfully solved Caesar and Vigenere pset but made and used an array that I stumbled upon through trial and error but don’t exactly know why and how it worked. I’m hoping someone could clarify it to me please. I’m actually very unhappy because I don’t know how and why it worked. Initially, and before stumbling into the end result of the array that I made and that worked perfectly for the solution and that passed all the checks, I used the basics I learned to make one. To make an array simply declare an array [ ], give it a name v[ ], and finally give it an integer size of the number of chars that will make up the string in it...i reviewed my notes and it confirms this, am I missing something? On the basis of what I have just mentioned I went ahead and did exactly that for the purpose of “storing” each ciphertext char in it, including spaces and punctuations, then after the whole ciphering process is done to print it out...to my surprise though my initial attempt, keeping in mind the basics of making an array, didn’t work or function as planned and got an error that pointed me in the direction of trying increasing the size of the array simply through dumb interpretation of the error; so I did just that v[strlen + 1] initially. That didn’t work and I got frustrated with curiosity on why that wouldn’t work as it should, so I added +100,000 to the strlen in array v and it worked like a charm! However now I’m really upset as I don’t know why it worked and also that I couldn’t figure out a better way to get the same result as probably everyone else did.

Here’s part of my code that I find relevant (not sure if I should reveal everything here, please tell me to remove it if I shouldn’t):

//If all char in argv[1] are alpabetic chars (function above), get the plaintext from the user string s = get_string("Plaintext: "); int g = strlen(s); char v[g + 8000000]; for (int i = 0, j = 0; i < g; i++) { //To address the chars in plain text that are alphabetic if (isalpha(s[i])) { //Converts string 'filtered from previous function' to an actual integer and MOD to wrap around array of argv[1] once all key chars are exhausted. key = shift(argv[1][j % n]); if (isupper(s[i])) { v[i] = ((s[i] - 'A' + key) % 26) + 'A'; } if (islower(s[i])) { v[i] = ((s[i] - 'a' + key) % 26) + 'a'; } //To go to the next letter in argv[1] j++; } //To not increment j (skip ciphering anything that is not alphabetic) else //To address the chars that are not Alphabetic { if (isspace(s[i])) { v[i] = ' '; } if (ispunct(s[i])) { v[i] = s[i]; } } } //Prints output printf("ciphertext: %s\n", v); } }

I really hope my inquiry is considered legit to ask here and to hopefully get a helpful explanation of why it is working like it is and why my initial attempt (I.e. without increasing the size of array v) did not work?

1 Answer 1

1

The detail you seem to miss is that a char array is not a string unless it ends in the NUL char '\0'

If you have char text[] = "Foobar";, that is stored

{'F', 'o', 'o', 'b', 'a', 'r', '\0'}

Without that final NUL char, if you were to printf("%s\n", text);, printf would only stop printing when it found a NUL, which may not necessarily be after the 'r' in memory.

When you created that really large array, you just happened to get memory that had zeroes in it, and it masked your issue.

The simplest solution with vigenere is not to create a new array to hold the ciphered chars, but to print each char as you go. (or, change the original chars and print that).

7
  • Assuming that I still wanted to use the array method to store my ciphered chars in it, how would one add the ‘NULL’ or ‘\0’ value seamlessly in the function I used, that used a loop, to mark the end of the array? I also thought that giving the array a specific size would implicitly tell/signal the array where to put the NULL or ‘\0’; in which case no need to add a NULL char myself (assuming that’s possible to do in the first place)
    – Jovanovic
    Sep 26, 2019 at 16:27
  • You have to set it yourself. If you declare int len = strlen(p); char array[len+1]; so that you have space for the null, then you can manually set array[len] = '\0';
    – curiouskiwi
    Sep 26, 2019 at 19:03
  • I mentioned that I did just that in my initial statement of my question “v[strlen + 1]” and it did not work. But then I added more larger numbers and eventually it worked. So I guess I’m now asking again why doesn’t your or my way work in the format that I used above? (I.e. replacing the “8000000” with “1” why does that not work?)
    – Jovanovic
    Sep 26, 2019 at 19:42
  • You don't show in your code where you ever set the null char.
    – curiouskiwi
    Sep 26, 2019 at 19:51
  • “Int g = strlen(s); char v[g + 8000000]” isn’t it automatically set at the end of any string and particularly “string(s)” in my example? I then got the strlen of s and just added 1 initially (to give space for the NULL char) but that didn’t work. Do literally hard code the NULL somewhere in the function? I feel I mightn’t be understanding you correctly, please don’t give up on me :) thank you!
    – Jovanovic
    Sep 26, 2019 at 20:06

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .