Thread: reading and replacing

  1. #1
    Unregistered
    Guest

    reading and replacing

    need help on replacing a string in a file.

    example of file:


    "mike" "1"
    "john" "2"
    "alan" "3"


    i need to search through the file for the name and replace the
    number that is assigned to name. Like if I was searching for
    john and needed to change his number from a "2" to a "3".

    here is what I have for the search part:

    #define MAXLINE 135
    char *k;
    int line_no = 0;
    char Delim[] = """";
    char strline[MAXLINE];
    FILE *fileptr;


    fileptr = fopen("name.cfg", "rw");
    while(fgets(strline, MAXLINE, fileptr))
    {
    line_no++;

    if ( strstr(strline,"mike")!=NULL)
    {
    k = strtok(strline, Delim);
    k = strtok(k + 15, Delim);
    printf("%s", k );
    break;
    }

    this returns the number like this "1"

    Thanks in advance.

  2. #2
    Registered User moi's Avatar
    Join Date
    Jul 2002
    Posts
    946
    char Delim[] = "\"\"";
    hello, internet!

  3. #3
    Unregistered
    Guest
    thanks for the reply, Thanks for the correct Delim. Can someone help me with replacing the number.


    Thanks.

  4. #4
    Unregistered
    Guest
    please anyone help on replacing ??


    thanks

  5. #5
    End Of Line Hammer's Avatar
    Join Date
    Apr 2002
    Posts
    6,231
    >strtok()
    You probably shouldn't be usng strtok() as it will alter the original string.

    >strline
    This is reserved name. You shouldn't create variables/function called str....

    Here's one way of doing it. It's a bit ugly, but it's safe. You could try putting some of it in a loop if you want, I didn't just to keep the example simple.
    Code:
    #include <stdio.h>
    #include <string.h>
    #include <ctype.h>
    
    int main(void)
    {
        /* line is
         "hammer" "1"
         */
        char line[] = "\"hammer\" \"1\"";
        char *p;
        
        printf ("Line is %s\n", line);
        
        if ((p = strstr(line, "hammer")) != NULL)
        {
            /* p now points to the h of hammer, increment and find " */
            p++;
            if ((p = strchr(p, '\"')) != NULL)
            {
                /* p now points to the " of hammer", increment and find next " */
                p++;
                if ((p = strchr(p, '\"')) != NULL)
                {
                    /* p now points to the " of "1, increment and update */
                    p++;
                    if (isdigit(*p))  /* Check it really is a number before updating */
                        *p = '2';
                }
            }
        }
               
        printf ("Line is now %s\n", line);
        return 0;
    }
    Please use code tags when posting code, and don't bump your threads.
    When all else fails, read the instructions.
    If you're posting code, use code tags: [code] /* insert code here */ [/code]

  6. #6
    End Of Line Hammer's Avatar
    Join Date
    Apr 2002
    Posts
    6,231
    OK, here's another version (I'm feeling kind today )
    Code:
    #include <stdio.h>
    #include <string.h>
    #include <ctype.h>
    
    #define QUOTES_TO_SKIP 3
    
    int main(void)
    {
        /* line is
         "hammer" "1"
         */
        char line[] = "\"hammer\" \"1\"";
        char *p;
        int i;
        
        printf ("Line is %s\n", line);
        
        if (strstr(line, "hammer"))
        {
            for (p = line, i = QUOTES_TO_SKIP;
                i && *p;
                p++)
            {
                if (*p == '\"') i--;
            }
            if (i == 0 && isdigit(*p))
                *p = '2';
        }
        printf ("Line is now %s\n", line);
        return 0;
    }
    When all else fails, read the instructions.
    If you're posting code, use code tags: [code] /* insert code here */ [/code]

  7. #7
    Unregistered
    Guest
    thanks for the help hammer. Ok, now i plug the code into the file and run the program but it doesn't change the number in the file.
    It prints on the screen what the new number should be but doesn't change it.

    thanks.

  8. #8
    End Of Line Hammer's Avatar
    Join Date
    Apr 2002
    Posts
    6,231
    It prints on the screen what the new number should be but doesn't change it.
    My code was only a sample to get you going. It sounds like you want to re-write to the file you are reading from. There various ways to do this, including re-writing everything to a new file, then renaming over the old one; or maybe, as you're only replacing one character, you could seek to the desired location and simply put that one char.

    Have a go, and see what you come up with.
    When all else fails, read the instructions.
    If you're posting code, use code tags: [code] /* insert code here */ [/code]

  9. #9
    beg_g
    Guest
    Hi,

    So I happened to be in a generous mood as I passed by, here's
    what I came up with, I've tried to include explanations as
    comments.

    Code:
            char *k;
            int line_no = 0;
    
            /*
             * The delimiting characters shall be the " and a space
             */
            char Delim[] = "\" ";
            char strline[MAXLINE];
            char search_for[] = "mike";
            int replace_with = 22;
            FILE *fileptr;
    
            fileptr = fopen("name.cfg", "r+");
            while(fgets(strline, MAXLINE, fileptr))
            {
                    line_no++;
                    if ((strstr(strline, search_for)) != NULL)
                    {
                            int i = 0;
                            char replacement[MAXLINE];
    
                            i = strlen(strline);
    
                            /*
                             * The code where the strtok() function is called is
                             * unnecessary here -- it is just a proof-of-concept
                             * ;)  The delimiters are the " and a space so
                             * you just supply the second argument of strtok
                             * with a string containing ALL of the EXPECTED
                             * delimiting characters for example if the
                             * delimiting characters were a colon ( : ) OR a
                             * comma (,) OR a period (.) then Delim would need
                             * to be defined like this:
                             *
                             * char Delim[] = ":,.";
                             *
                             * I hope that makes strtok clear otherwise in this
                             * simple case I illustrate (simple search and replace)
                             * it is not really needed.
                             */
                            k = strtok(strline, Delim); /* k is now mike */
                            k = strtok(NULL, Delim); /* k is now the number assoc with mike */
                            /*
                             * If you want to be sure, you could slot in a printf
                             * statement to see what k is -- it should be the value
                             * associated with "mike".
                             *
                             * Next we build up the line we want to replace (for simplicity
                             * we shall replace the whole line but only changing the number
                             * associated with the name)
                             */
                            sprintf(replacement, "\"mike\" \"%d\"", replace_with);
                            /*
                             * The (possibly) trickier part: replacing the contents
                             * of the file.  Here you use the functions ftell and fseek
                             * to set the file pointer to the beginning of the line
                             * you want to replace.  That is why we needed the initial
                             * length of the line -- to know exactly where to place the
                             * file pointer.  So we overwrite the old value with the new
                             * one.  To leave things simple, we'll assume that the number
                             * associated with the name comprises of TWO digits.  So when
                             * we overwrite the old value, it gets completely overwritten
                             * Food for thought:  If the number associated with the name is
                             * more than 2 digits, what would you do?  I leave that to you.
                             *
                             * Look up the documentation on fseek, it's not hard.
                             */
                            fseek(fileptr, ((ftell(fileptr))-i), SEEK_SET);
                            /*
                             * The stream pointer is now at the beginning of the line,
                             * we replace the old line
                             */
                            fprintf(fileptr, "%s\n", replacement);
                            break;
                    }
            }
            fclose(fileptr);
    }
    You might want to check if the fopen() failed too -- usually good
    for debugging.

    Have fun,
    Gerald.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Why isn't my program reading my file properly?
    By DCMann2 in forum C Programming
    Replies: 10
    Last Post: 04-23-2008, 01:16 AM
  2. Hello, bored reading and a bunch of questions.
    By Jorl17 in forum C++ Programming
    Replies: 13
    Last Post: 04-03-2008, 05:43 PM