1. Limited time only! Sign up for a free 30min personal tutor trial with Chegg Tutors
    Dismiss Notice
Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

Help with pointers and strings in C

  1. May 8, 2017 #1
    1. The problem statement, all variables and given/known data
    I have to create a program that dynamically allocates a string and uses up no extra space (The string takes up as much space as it needs to),checks if entered string is 'please stop this', if it is then the prgogram exits and if it isn't then it continues, it makes a copy of that string and then searches through it to find every reaccurence of charachter 'a' and change it to 'i go first in the alphabet' then print out both the original string and the changed one.
    3. The attempt at a solution
    Here is my thinking:
    I will create a pointer to a string and for each inputted charachter i will reallocate so that it uses just as much as i need it to.
    Code (C):

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

    int main() {
        char *string, c, t;
        int i = 0, k = 1;

        string = (char*)malloc(sizeof(char));

        printf("Enter your string: \n");

        while (c != '\n') {
        c = getc(stdin);

        // I am reallocating for each charachter inputted
        string = (char*)realloc(string, k * sizeof(char));
        string[i] = c;
        i++;
        j++;
      }

      string[i] = '\0';

      printf("\nYou entered : %s", string);

      free(string);
    }
     
    This seems to do the job so far. Now i need to add the part where i check the string, if it passes copy the string and do the modifications on that copy. I believe i managed to get the copying right but fail at comparing the strings.

    Code (C):

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

    int main() {
        char *string, c, *t;
        int i = 0, k = 1;

        string = (char*)malloc(sizeof(char));

        printf("Enter your string: \n");

        while (c != '\n') {
        c = getc(stdin);

        // I am reallocating for each charachter inputted
        string = (char*)realloc(string, k * sizeof(char));
        string[i] = c;
        i++;
        k++;
      }
      string[i] = '\0';
     
      // The part where i check if strings equals the invalid input. Dont know whats the case here..
      if (strcmp(string,"please stop this") == 1) {
        printf("You wanted to stop so here we go! \n");
        return 0;
      }
     
      // The part where i copy the string into the new pointer t
      t = (char*)malloc(strlen(string)*sizeof(char));
      strcpy(t, string);

     

      printf("\nThe entered string is : %s", t);

      free(string);
      free(t);
    }
     
    I cant continue without this. What seem to be wrong, i cant figure it out, why isnt it comparing the strings? It allows every to pass
     
  2. jcsd
  3. May 8, 2017 #2
    It doesn't work because of these reasons:
    - Your code still adds the \n to the string, so you should not do this, or compare the string to to "please stop this\n"
    - strcmp returns a 0 if the strings are equal.
    also
    -c isn't initialized the first time.
    -you do not allocate enough memory for the newline AND the ending 0. In visual studio 2017, I get a "HEAP CORRUPTION ERROR" if i compile this to a console application and run it.
     
  4. May 9, 2017 #3
    With a little help i made some important changes to the entire program and now it compares and copies the strings the right way. Another importnat thing is that the mission of my program has changed. The correction was made so that my program should find every ocurrence of a number in a string and change it to a letter name ( '1' - 'one').If there are two numbers one after another they should be separated by -.I tryed to do that but i dont think its right and it will take too long to do like i started. I will post the code so you can pinpoint the mistakes and correctios i should make;
    Code (C):

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

    void main() {
        char *old_p = NULL, *new_p, c, *str_copy, *strC;
        char *str0= "zero";
        int i = 0;
        printf("Enter string: \n");
    //Allocating now for every charachter inputted by the user
        while ((c = getchar()) != '\n') {
            if ((i % 10) == 0) {
                new_p = realloc(old_p, (i + 10) * sizeof(char));
                if (new_p == NULL) {
                    printf("Failed to allocate. \n");                              
                    break;
                }
                else {
                    old_p = new_p;
                }
            }
            old_p[i++] = c;
        }
    //Reallocating one more time to add the zero element
        new_p = realloc(old_p, (i + 1) * sizeof(char));
        if (new_p == NULL) {
            printf("Failed to allocate. \n");
            exit(0);
        }
        else {
            old_p = new_p;
        }
        old_p[i] = '\0';

    //Checking if the string matches
        if (strcmp(old_p, "please stop this!") == 0) {
            printf("The strings match. The program will exit. \n");
            exit(0);
        }
    //Allocating and copying the string
        str_copy = (char *)calloc(strlen(old_p) + 1, sizeof(char));
        if (str_copy == NULL) {
            printf("Failed to allocate. \n");
            exit(0);
        }

        strcpy(str_copy, old_p);

    //The main problem of my program. It goes through the string and checks fo the numbers
        for (i = 0; i < strlen(str_copy); i++) {
    //In the ASCII codes the numbers 0-9 go from 48 - 57. I dont check for numbers that follow numbers because i dont do this part propery=ly
            if (str_copy[i] >= 48 && str_copy[i] <= 57) {
                    switch (str_copy[i])
                    {
                    case 48:
                    {
    //Here i would basically go fro every case and do the same exept for the change in letters that make that number.
                        strC = (char *)calloc(strlen(str_copy)+strlen(str0), sizeof(char));    //I allocate another string pointer to hold i elements of string
                        strncpy(strC, str_copy, i);
                        strC[i] = '\0';   //I append the zero element
                        strcat(strC, str0);  //I now append the first i elements of the original string with the name of number
                        strcat(strC, str_copy + (i+1));   //I now append the rest of the oriinal string
                        str_copy = (char *)calloc(strlen(strC) + 1, sizeof(char));   //I allocate the original string to hold the changed string, change the i to count from where its suppose to and continue. Imagine doing this for all cases and the case where i put - also! Huh.
                        strcpy(str_copy, strC);
                        i += strlen(str0);
                        free(strC);
                    }
                    }
            }
        }

        printf("Your original string is: %s\n", old_p);
        printf("Your changed string is: %s\n", str_copy);
        free(old_p);
        free(str_copy);
    }
     
    Do you have any thoughts on this?
     
  5. May 9, 2017 #4
    I think i got it, its still about 250 lines of code but it works..
     
  6. May 9, 2017 #5
    I really hate using all those old-style c strings and string functions. Very easy to make errors, espescially if you reallocate strings all the time and have to set those ending zeroes yourself.
     
  7. May 9, 2017 #6
    Do you have an idea of how i would incorporate this into the code:
    I am supposed to have a big while loop that lets you enter strings until you enter "please stop!". Basically a big While aroung the program that is true until the program exists by "please stop" and when i do enter that it should print out every string that i entered and its changed string.
    For example if i entere some string and get its result and do the same for a couple of strings more when i enter "please stop!" it should print a pair of string-result that i got. I cant seem to have an idea on how to do this..
     
  8. May 9, 2017 #7

    Mark44

    Staff: Mentor

    It seems extremely inefficient to me to call malloc() for each character entered. I can't imagine that a "real" production program would do this. Since I don't know the exact wording of your program requirements, it's hard to say what your instructor wants you to do.

    A possibility might be to use a temporary array of type char that's large enough to hold any reasonably sized strings, say char temp[100]. After you have read in a string of characters, allocate enough dynamic memory from the heap (i.e., call malloc()) to get exactly the right amount of memory, and copy the characters to the dynamic memory.

    So you need to search through your string looking for the digits 0 through 9. When you find a digit, you will need to replace the digit (one character) by anywhere from three characters ("one", "two", "six") up to five characters ("three", "seven", "eight"). I'm assuming you are using the English names for the characters, but I know that your native language isn't English, but I think you probably get the idea.

    If you run across, say, a 1 digit, I think I would use malloc() to get enough memory for two more bytes. You will then need to copy all the characters of the first string up to the 1 digit, then copy "one", then copy the remainder of the original string, including the termination null character.
    For the "please stop!" string, you should use strcmp() function, whose declaration is in the header string.h. There are also declarations for strcat() (concatenate -- join-- two strings, strchr() -- find first occurrence of a character within a string, strstr() -- find first occurrence of a string within anohther string, and a bunch of others.

    Hope this helps!
     
  9. May 9, 2017 #8
    Thanks for the answer :). I agree with you that its highly inefficient to allocate for every string but its what they want me to do. They don't care about the efficiancy at all. My problem now is described in my last post. Like in the other programs i posted i need to have a while loop to run the program in a lopp until the string "please stop" is entered. At that moment i finish the program by printing out every original string entered by the user while in a loop an its result.
    I have an idea on how to do this but get an error when i implement. Let me describe what i think should be done:
    Lets suppose your the program runs correctly that as its loop output prints the riginal and the changed string. I should independently of the loop and all in it create two pointers, one for some int array lets call it LENGTHS and one for the strings array lets it TEXT.
    After each completion of the loop i shoud :
    1) reallocate the TEXT to hold the size of these two strings that are outputted by the loop.
    2)append the strings to the TEXT
    3)reallocate the LEGTHS to hold two numbers (lengths of strings)
    4)Make some k-th array element be the length of string 1 and some k+1 length of string 2. (k starts at 0 and increases by 2 so not to mix the elements)
    When you enter "please stop" the loop exits and i print out the TEXT helping myself with the numbers from the LENGTHS array as to know at which place each string finishes. What do you think about this?
     
Know someone interested in this topic? Share this thread via Reddit, Google+, Twitter, or Facebook

Have something to add?
Draft saved Draft deleted



Similar Discussions: Help with pointers and strings in C
  1. Help with C++ strings (Replies: 3)

Loading...