Thread: Changing char in Pointer String?

  1. #1
    Registered User
    Join Date
    Oct 2002
    Posts
    24

    Changing char in Pointer String?

    Hey im making an encryption program... its going to be a simple one but it will do the job for what i need it for... I need to take a string which is inputed to a sting pointer Via a file... Then i need to add a certain number such as 1 to the letter of each string and put that letter back in the string... for example

    Code:
    char *s;
    
    s = "abcd";
    i need to change it to bcde

    this is what i have so far

    Code:
    #include <stdio.h>  /* header file  */
    #include <stdlib.h>
    void main(void)
    {
     
     FILE *fp;   /* file pointer */
    char *i,c;
    
     int count;
     /* open file for output */
     if ((fp = fopen("myfile", "w"))==NULL){
      printf("Cannot open file \n");
      exit(1);
     }
     
     i="abcdef"; /*here is my string*/
    
     for(count=0;(i[count] != '\0'); count++){
    	 c = (i[count] + 28); /*here i convert the integer value to a char*/
         /* here i need some way of putting that char back into the string*?
     }
     
     
     if (fwrite(&i, 2, 1, fp) !=1){
      printf("Write error occurred");
      exit(1);
     }
     fclose(fp);
     
     /* open file for input */
     if ((fp =fopen("myfile", "r"))==NULL){
      printf("Read error occurred");
      exit(1);
     }
     printf("\ni is %s\n",i);
     fclose(fp);
     getchar();
    }

  2. #2
    Registered User Pioneer's Avatar
    Join Date
    Dec 2002
    Posts
    59
    You don't need to put it back into the string, just add the number right to the character in the string. chars are just little ints anyway, here, I'll show you:
    Code:
    main(){
        int x;
        char *string, *step;
        
        printf("What's your name? ");
        string = sgets();
    
        printf("Enter a step to encryt by: ");
        step = sgets();
        
        for (x = 0; string[x]; x++)
            string[x] += atoi(step);
        
        printf("%s\n", string);
        
        for (x = 0; string[x]; x++)
            string[x] -= atoi(step);
        
        printf("%s\n", string);
    }

  3. #3
    Registered User
    Join Date
    Oct 2002
    Posts
    24
    what is sgets() and why does my compiler give an error when i use it?

  4. #4
    Registered User moi's Avatar
    Join Date
    Jul 2002
    Posts
    946
    your guess is as good as mine, its certainly not an ansi standard library function
    hello, internet!

  5. #5
    Registered User Pioneer's Avatar
    Join Date
    Dec 2002
    Posts
    59
    It's my safe gets function, you can use mine if you want or your favorite line reading function, the program won't care.
    Code:
    char *sfgets(FILE *src){
        typedef struct list{int val; struct list *n;}LIST;
    
        int i, c = 0;
        char *string;
        LIST *head = malloc(sizeof(LIST)), *walk = head;
    
        while ((i = getc(src)) != '\n' && (walk->n = malloc(sizeof(LIST))))
            walk = walk->n, walk->val = i, walk->n = 0, c++;
    
        string = calloc(c + 1, sizeof(char));
        
        for (i = 0, walk = head->n; walk; walk = walk->n)
            string[i++] = walk->val;
    
        return(string);
    }
    
    char *sgets(){
        return sfgets(stdin);
    }

  6. #6
    End Of Line Hammer's Avatar
    Join Date
    Apr 2002
    Posts
    6,231
    @Pioneer

    string is a reserved name, so avoid using it.
    To use malloc() don't forget to include stdlib.h.
    Don't forget to check for EOF, else the program could go into an infinite loop.
    Calling malloc() every time you read one character is a expensive way to do business, imho.
    Using calloc() is unnecessary for two reasons, 1) you've already malloc()'d more than enough memory to hold your data. 2) There's no need to initialise every byte to zero when the first thing you do is write over them all (except the terminating NULL).
    If you're using dynamic memory, you must remember to free it when you're done. You're sfgets() functions leaks like crazy at present
    When all else fails, read the instructions.
    If you're posting code, use code tags: [code] /* insert code here */ [/code]

  7. #7
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    i="abcdef"; /*here is my string*/
    Furthermore, unless I'm mistaken because I'm tired, you aren't allowed to change the string "abcdef". Sure, you can tell the pointer to point to something else. But you cannot change the individual characters of that string becaues that string is not an array. It's a string literal. You cannot change string literals.

    No, this isn't what you're doing exactly in your case, but it is an error in the first code you've provided, so I thought I'd point it out.

    Had you done:

    char i[] = "abcdef";

    Then you could change the individual characters. Of course, then you couldn't just make direct full string assignments, but that's the trade off you have to make...

    Quzah.
    Hope is the first step on the road to disappointment.

  8. #8
    Registered User Pioneer's Avatar
    Join Date
    Dec 2002
    Posts
    59
    string is a reserved name, so avoid using it.
    I don't want to sound mean, but can you prove that? I see it way too much to believe that it's wrong.
    To use malloc() don't forget to include stdlib.h.
    I did, I just didn't post that part of the program.
    Don't forget to check for EOF, else the program could go into an infinite loop.
    Thanks!
    Calling malloc() every time you read one character is a expensive way to do business, imho.
    It gets the job done, and performance really doesn't matter much to me. Anyway, it's not even noticeable and I find sgets easier to use than gets.
    Using calloc() is unnecessary for two reasons, 1) you've already malloc()'d more than enough memory to hold your data. 2) There's no need to initialise every byte to zero when the first thing you do is write over them all (except the terminating NULL).
    But it ends up looking cleaner than using malloc and adding the NULL later.
    If you're using dynamic memory, you must remember to free it when you're done. You're sfgets() functions leaks like crazy at present
    Windows takes back any memory I use when the program ends, so there's no leak.

  9. #9
    Registered User moi's Avatar
    Join Date
    Jul 2002
    Posts
    946
    >>I don't want to sound mean, but can you prove that? I see it way too much to believe that it's wrong.
    He's right, string is reserved word.
    >>Windows takes back any memory I use when the program ends, so there's no leak.
    Very poor form, and not true of all OSes. also gives great problems when you try to write something that will run for any length of time.
    hello, internet!

  10. #10
    End Of Line Hammer's Avatar
    Join Date
    Apr 2002
    Posts
    6,231
    >>I don't want to sound mean, but can you prove that?
    Yes, I can prove it, or I wouldn't have said it I have done so on previous occasions, and so have others on this board. Try a search and you might find a previous thread on this.

    >>I see it way too much to believe that it's wrong.
    Hmmm.... I'd question what you read then.

    >>stdlib.h ... just didn't post that part of the program
    Fair enough from your point of view, but remember that other people reading your posts maybe newer than you and may not know they have to include certain files.

    >>Windows takes back any memory I use when the program ends, so there's no leak.
    Nasty! As moi said, write anything that either runs long term, or processes large amounts of data, and you'll soon run into trouble. For example, your function reads a line, and stores each char in a struct/link list. Each node (ie structure) on my compiler comes weighing in at 8 bytes. You are throwing away 8 bytes of memory for every byte of real input. Apply the maths to an input file of say 20mb and see how much RAM you have left at the end. Your program might only take few seconds to read the whole file in too.
    When all else fails, read the instructions.
    If you're posting code, use code tags: [code] /* insert code here */ [/code]

  11. #11
    Registered User Pioneer's Avatar
    Join Date
    Dec 2002
    Posts
    59
    Kay, here's the function with a bunch of changes made that reflect what I learned in this thread and from my book. Now it reclaims it's own memory, tracks the memory to make sure, and checks for more error conditions. I also got rid of calloc even though I'm not sure it makes any difference. Did I get everything, except for using the expensive list that is, I still think it's a good way to do it.
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    #pragma warning(disable: 4706)
    
    char *sfgets(FILE *src);
    char *sgets();
    
    #define TRACKMEMORY
    #if defined(TRACKMEMORY)
        int trackmem;
        #define tmalloc(x) (trackmem++, malloc((x)))
        #define tfree(x) (trackmem--, free((x)))
        #define tprint printf("Leaked memory calls: %d\n", trackmem)
    #else
        #define tmalloc(x) (malloc((x)))
        #define tfree(x) (free((x)))
        #define tprint
    #endif
    
    main(){
        char *s;
    
        printf("What's your name? ");
        s = sgets();
        printf("Heyas, %s!\n", s);
        tfree(s);
        tprint;
    }
    
    char *sfgets(FILE *src){
        typedef struct list{int val; struct list *n;}LIST;
    
        int i, c = 0;
        char *dst;
        LIST *head = tmalloc(sizeof(LIST)), *save, *walk = head;
    
        if (!head)
            return 0;
        while ((i = getc(src)) != '\n' && i != EOF){
            if (!(walk->n = tmalloc(sizeof(LIST))))
                break;
            walk = walk->n, walk->val = i, walk->n = 0;
            c++;
        }
        if (!(dst = tmalloc(c * sizeof(char)+1)) && !c)
            return 0;
        for (i = 0, walk = head->n; walk; walk = save){
            save = walk->n;
            dst[i++] = (char)walk->val;
            tfree(walk);
        }
        tfree(head);
    
        return(dst[i] = 0, dst);
    }
    
    char *sgets(){
        return sfgets(stdin);
    }

  12. #12
    Registered User moi's Avatar
    Join Date
    Jul 2002
    Posts
    946
    Originally posted by vVv
    >>Windows takes back any memory I use when the program ends,
    >> so there's no leak.
    >Very poor form, and not true of all OSes.

    This is bogus. free( ) isn't even guaranteed to return memory to the operating system, the BSD implementation for example does a madvise( ) call with MADV_FREE on the pointer, telling the OS that the page is no longer needed - doesn't mean the memory manager immediately takes it back. An implementation might also choose to retain the pages for further malloc( ) calls. And eventually, you're not even guaranteed that your text, stack and data segments are freed after termination. This is more of a ``Quality of Implementation'' issue, and a system that doesn't ``take the memory back'' is seriously broken.
    the fact that free() might not return the memory to the operating system is irrelevant. it returns it to it's internal heap in many systems, the point is it knows what is not being used. it will return the memory to the system on normal termination.

    the C standard makes no requirement of a stack, and i doubt it even mentions data or text segments, so tell me again why you're reffering to them? if an implementation has such things, it is it's responsibility to allocate and free memoy for them. an implementation that doesn't take back what you don't give it back is 101% working fine. anything else that it decides it needs but you don't allocate explicity, is it's responsibility, yes.
    hello, internet!

  13. #13
    Registered User moi's Avatar
    Join Date
    Jul 2002
    Posts
    946
    Originally posted by vVv
    Well, I thought

    > it will return the memory to the system on normal termination.

    was what you're trying to argue with

    >Very poor form, and not true of all OSes.

    and that's the only reason why I posted. Besides, only because the C standard doesn't mention implementation-specific issues doesn't mean you have to throw all common sense away and ignore them or consider them irrelevant - you won't get far that way. And I guess you have never even compiled code on platforms other than x86/Windows98 (and perhaps DOS) so I'm wondering why you keep fighting everything ``nonstandard'' so hard, where you don't even have to worry about that - care to elaborate?
    all i'm saying is a conforming implementation will return all memory to the OS except possibly that which you dont free (). a nonconforming implememntation might not even return your watch after it steals it from you. don't count on memory which you malloc() explicity but do not free() ever getting back to where it belongs. if you like to program explicity for one system, and you don't like typing the word free(), than fine, do whatever you want. as far as considering implementation specific issues irrelevant, i'm not, but you're going the wrong way with them so to speak. if an implementation has a certain deficit below the standard, then depending on your target audience and platform, you may want to deal with that deficit, even when writing standard code. on the other hand, if an implementation goes above and beyond the call of duty (as those do that return non-free()d memory to the system upon normal program termination), there is still no reason to take advantage of that feature unless you are making something platform specific here.

    but let's step back to the original question: should one free() what one malloc()s? no doubt about it. otherwise you might as well write java
    hello, internet!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. sorting number
    By Leslie in forum C Programming
    Replies: 8
    Last Post: 05-20-2009, 04:23 AM
  2. OOP Question DB Access Wrapper Classes
    By digioz in forum C# Programming
    Replies: 2
    Last Post: 09-07-2008, 04:30 PM
  3. Program using classes - keeps crashing
    By webren in forum C++ Programming
    Replies: 4
    Last Post: 09-16-2005, 03:58 PM
  4. Contest Results - May 27, 2002
    By ygfperson in forum A Brief History of Cprogramming.com
    Replies: 18
    Last Post: 06-18-2002, 01:27 PM
  5. How do you search & sort an array?
    By sketchit in forum C Programming
    Replies: 30
    Last Post: 11-03-2001, 05:26 PM