0

I have this code:

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

string increment_str();

int  main() {
   string s = increment_str("xyz");
   printf("String: %s\n", s);
}

//Increment the characters of a string through lowercase and then uppercase alphabet
string increment_str(string s)
{
   int len = strlen(s);
   // Initialize an r var to make sure s_return has enough space in memory
   char r[len];
   string s_ret = r;

   //Remove the last character so the incremented one can be concatenated later
   strcpy(s_ret, s);
   s_ret[len - 1] = '\0';

   switch (s[len - 1])
   {
      //At the end of lowercase alphabet start over at uppercase
      case 'z':
         strcat(s_ret, "A");
         return s_ret;
         break;

      case 'Z':
         //If all the the first character is the last letter start over with an extra character
         if (len == 1)
         {
            strcpy(s_ret, "aa");
         }
         //Else refer to itself to increment the previous character in string
         else
         {
            strcpy(s_ret, increment_str(s_ret));
            strcat(s_ret, "a");
            return s_ret;
         }

      //Needs brackets because you can't declare a var after a case
      default:
      {
         //Concatenates the increased character with the string before it
         char c[2] = {s[len - 1] + 1, '\0'};
         strcat(s_ret, c);
         return s_ret;
      }
   }

}

That should run normally, and it does in fact, except when it gets to the part of printing. Through debug50 I can see step by step how everything is going but when it tries to print s it always prints "U" if run through debug50 or other garbage if run normally as seen in the screenshots bellow:

Before print After print After print, no debug

I am really not sure why this is happening or how to solve it so any help would be appreciated :)

0
char r[len];
string s_ret = r;

The issue is that s_ret is pointing to a local variable r, which goes out of scope once the function returns. Therefore, the "string" you are returning to main is no longer valid, so you will get garbage.

If this is for caesar, I'd suggest it is a too-complicated approach until you learn more about char pointers and the fact that there is no such thing as a "string" type in C.

If you are trying to "wrap around" the alphabet, it is far simpler to deal with it mathematically (bring the char down to the range of 0-25 and use %26 to wrap it around, such that 'z' + 1 will be 'a'. ( 'z'-'a' is 25, and 25+1 is 26, 26%26 is 0 and 0+'a' is 'a').

  • This is actually for crack, so as far as I can tell I need to "wrap around" the lowercase AND uppercase alphabet to generate keys to try to "bruteforce" the hash, so I believe I can't just use a modulo approach. And referring to pointing to r, is there any way I can dynamically tell string how long I want it to be without pointing to another variable? If I just declare without initializing it I get a segmentation fault. I think I'm starting to get a grasp on strings as character arrays or pointers but I'm still not quite sure, I wouldn't mind a technical explanation though :) – C1N14 Jul 1 '18 at 16:17
  • presumably you are planning to loop over the alphabet to build your string? Why not simply say "if it's 'Z', then add +7 instead of +1" and that will take you to 'a'. I'd rather not recreate an entire lecture on strings so if you'd prefer to use pointer methods, etc, I'd suggest postponing the crack problem for a week or two and come back to it after the lectures dealing with strings. – curiouskiwi Jul 1 '18 at 21:34
  • In the end I ended up ditching string completely and using char * pointers (which I'm almost sure the string objects are, anyways), and malloc() and memcpy() insted of using r as a middle man to make sure s_ret had enough space. – C1N14 Jul 2 '18 at 20:31
  • string is simply a typedef for char * – curiouskiwi Jul 2 '18 at 23:51

You must log in to answer this question.

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