Help with pointers and strings in C

In summary, the programmer attempted to solve the problem of space allocation by dynamically allocating a string, checking if the entered string is 'please stop this', and if it is then the program exits, else it continues. They also copied the string to a new pointer, and if the entered string is not 'please stop this', then compared the strings. If the strings are equal, then the program prints out the entered string and exits. If the strings are not equal, then the programmer makes changes to the copied string, and tries to compare it again.
  • #1
doktorwho
181
6

Homework Statement


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.

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.
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.

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 what's 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 can't continue without this. What seem to be wrong, i can't figure it out, why isn't it comparing the strings? It allows every to pass
 
Physics news on Phys.org
  • #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.
 
  • Like
Likes doktorwho
  • #3
willem2 said:
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.
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 don't 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;
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 don't check for numbers that follow numbers because i don't 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?
 
  • Like
Likes willem2
  • #4
I think i got it, its still about 250 lines of code but it works..
 
  • #5
doktorwho said:
I think i got it, its still about 250 lines of code but it works..

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.
 
  • #6
willem2 said:
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.
Do you have an idea of how i would incorporate this into the code:
I am supposed to have a big while loop that let's 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 can't seem to have an idea on how to do this..
 
  • #7
doktorwho said:
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.
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.

doktorwho said:
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 -.
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.
doktorwho said:
Do you have an idea of how i would incorporate this into the code:
I am supposed to have a big while loop that let's 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 can't seem to have an idea on how to do this..
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!
 
  • #8
Mark44 said:
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!
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 let's call it LENGTHS and one for the strings array let's 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?
 

1. What is the difference between a pointer and a string in C?

A pointer in C is a variable that holds the memory address of another variable. It is used to indirectly access and manipulate data stored in memory. A string in C is an array of characters, typically used to store and manipulate text data. A string can be accessed and manipulated using a pointer.

2. How do I declare and initialize a pointer in C?

To declare a pointer in C, you use the asterisk symbol (*) before the variable name. For example: int *ptr; To initialize a pointer, you can assign the memory address of another variable using the & operator. For example: int x = 5; int *ptr = &x; This assigns the memory address of x to the pointer ptr.

3. What is the purpose of using pointers with strings in C?

Pointers are commonly used with strings in C because strings are essentially arrays of characters and can be accessed and manipulated using pointers. Pointers allow for more efficient and flexible manipulation of strings, as you can easily change the value of a character or traverse through the string using pointer arithmetic.

4. How do I allocate memory for a string using pointers in C?

To allocate memory for a string using pointers in C, you can use the malloc() function. This function takes in the number of bytes to allocate and returns a pointer to the first byte of the allocated memory. For example: char *str = (char *) malloc(50 * sizeof(char)); This allocates 50 bytes of memory for the string and assigns the address to the pointer str.

5. Can I use pointers to compare two strings in C?

Yes, you can use pointers to compare two strings in C. The strcmp() function allows you to compare two strings using pointers. It returns an integer value that indicates if the strings are equal, with 0 indicating equality. You can also compare individual characters using == or != operators on pointers to the characters in the strings.

Similar threads

  • Engineering and Comp Sci Homework Help
Replies
2
Views
944
  • Engineering and Comp Sci Homework Help
Replies
17
Views
1K
  • Engineering and Comp Sci Homework Help
Replies
2
Views
1K
  • Engineering and Comp Sci Homework Help
Replies
11
Views
2K
  • Engineering and Comp Sci Homework Help
Replies
3
Views
669
  • Engineering and Comp Sci Homework Help
Replies
2
Views
2K
  • Engineering and Comp Sci Homework Help
Replies
2
Views
1K
  • Engineering and Comp Sci Homework Help
Replies
12
Views
2K
  • Engineering and Comp Sci Homework Help
Replies
7
Views
1K
  • Engineering and Comp Sci Homework Help
Replies
3
Views
883
Back
Top