Quick Ques on String Manipulation

This is a discussion on Quick Ques on String Manipulation within the C Programming forums, part of the General Programming Boards category; I just want to thank all the people that responded when I first posted a question about a project I'm ...

  1. #1
    Registered User
    Join Date
    May 2008
    Posts
    16

    Quick Ques on String Manipulation

    I just want to thank all the people that responded when I first posted a question about a project I'm working on... Esp. Elysia. Very Helpful.

    I had two quick questions:

    The following program is going to be used to format text to certain standards set by our senior editors for a new organization that I work for. In the latter parts of the program, I'm trying to recognize the strings for the date, and I clearly want to be able to use a for loop, but obv you can't increment a string value. Is there a way to implement atoi() or something similar to be able to recognize that part of the string, then convert it to be able to make it more efficient? You'll clearly see the inefficiency that is curr. in place in the lower parts of the date_func().

    And is there any way to implement regular expressions in C? Sorry if this is a stupid question, I"m def. still a noobie, but really trying to push myself forward with a workable and useful project.

    Thanks in advance for your responses.
    This board is a great resource.

    -Chris

    ===============================

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    int url_func();
    int title_func();
    int author_func();
    int source_func();
    int date_func();
    
    FILE *stream_f1;
    FILE *stream_f2;
    
    char *my_string;  
    int i = 0;
    long position = 0;
    
    
    int main() {
    
      int c;
    
      int buffersize = 100;
      int charsRead  = 0;
    
      
      my_string = (char *) malloc (buffersize * sizeof(char));
    
      stream_f1 = fopen ("sub.txt", "r");
      stream_f2 = fopen ("formatted_sub.txt", "w");
    
      do {
        charsRead = getline (&my_string, &buffersize, stream_f1);
        if (charsRead == -1) break;
      
        while (i <= 4) { 
        	if (i == 0) {
    	  position = ftell (stream_f1);
    	  url_func();
    	}
    
    	if (i == 1) {
    	  date_func();
    	}
    	/*
    	if (i == 1) {
    	  title_func();
    	}
    	if (i == 2) {
    	  author_func();
    	}
    	if (i == 3) {
    	  source_func();
    	}
    
    	*/	
    	break;
        }
    
        if (i > 4) {
        fprintf (stream_f2, "%s", my_string);
        printf("%s", my_string);
        }
        else fseek (stream_f1, position, SEEK_SET);
      } while (charsRead >= 0);   
    
      printf ("\n");
      fprintf (stream_f2, "\n");
      free(my_string);
      fclose (stream_f1);
      fclose (stream_f2);
    
      return 0;
    }
    
    /*  Function to obtain URL string     *******************************************************
    *********************************************************************************************/
    int url_func() {
    
      if (strstr (my_string, "http")) {
        ++i;
        printf ("%s", my_string);
        fprintf (stream_f2, "s", my_string);
      }
    return 0;
    }
    
    /*  Function to obtain date string    *******************************************************
    **********************************************************************************************/
    int date_func() {
    
      char *day_num;
      char *aa, *bb, *cc, *dd;
    
      do {
        if (strstr (my_string, "mon") || strstr (my_string, "Mon") || strstr (my_string, "MON")) {
          aa = "Monday";
        }
        else if (strstr (my_string, "tues") || strstr (my_string, "Tues") || strstr (my_string, "TUES")) {
          aa = "Tuesday";
        }
        else if (strstr (my_string, "wed") || strstr (my_string, "Wed") || strstr (my_string, "WED")) {
          aa = "Wednesday";
        }
        else if (strstr (my_string, "thurs") || strstr (my_string, "Thurs") || strstr (my_string, "THURS")) {
          aa = "Thursday";
        }
        else if (strstr (my_string, "fri") || strstr (my_string, "Fri") || strstr (my_string, "FRI")) {
          aa = "Friday";
        }
        else if (strstr (my_string, "sat") || strstr (my_string, "Sat") || strstr (my_string, "SAT")) {
          aa = "Saturday";
        }
        else if (strstr (my_string, "sun") || strstr (my_string, "Sun") || strstr (my_string, "SUN")) {
          aa = "Sunday";
        }
        else ;
      }
      //  Next Do Statement
      do {
        if (strstr (my_string, "01") || strstr (mystring, "1")) {
          bb = "01";
        }
        if (strstr (my_string, "02") || strstr (mystring, "2")) {
          bb = "02";
        }
        if (strstr (my_string, "03") || strstr (mystring, "3")) {
          bb = "03";
        }
        if (strstr (my_string, "04") || strstr (mystring, "4")) {
          bb = "04";
        }
        if (strstr (my_string, "05") || strstr (mystring, "5")) {
          bb = "05";
        }
        if (strstr (my_string, "06") || strstr (mystring, "6")) {
          bb = "06";
        }
        if (strstr (my_string, "07") || strstr (mystring, "7")) {
          bb = "07";
        }
        if (strstr (my_string, "08") || strstr (mystring, "8")) {
          bb = "08";
        }
        if (strstr (my_string, "09") || strstr (mystring, "9")) {
          bb = "09";
        }
        if (strstr (my_string, "10") {
          bb = "10";
        }
        if (strstr (my_string, "11") {
          bb = "11";
        }
        if (strstr (my_string, "01") || strstr (mystring, "1")) {
          bb = "01";

  2. #2
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,048
    And is there any way to implement regular expressions in C? Sorry if this is a stupid question, I"m def. still a noobie, but really trying to push myself forward with a workable and useful project.
    Not in C per se, but you can use regular expression libraries that do the same thing. I've never really tried them myself, but you could try "man regex".


    [edit]
    The following program is going to be used to format text to certain standards set by our senior editors for a new organization that I work for. In the latter parts of the program, I'm trying to recognize the strings for the date, and I clearly want to be able to use a for loop, but obv you can't increment a string value. Is there a way to implement atoi() or something similar to be able to recognize that part of the string, then convert it to be able to make it more efficient? You'll clearly see the inefficiency that is curr. in place in the lower parts of the date_func().
    I'm not sure what you're trying to do here, sorry. Are you just trying to get a number out of a string, a numerical representation of the date, as it were?

    Another observation: you should write a case-insensitive clone of strstr(). It would make your life a lot easier. [/edit]

    [edit=2] I think you also need "while" statements to match up with your "do" statements . . . . [/edit]
    Last edited by dwks; 06-21-2008 at 05:47 PM.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  3. #3
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Posts
    22,915
    I'm glad you didn't take all lessons to heart, because I see two (probable) mistakes that you did last time:

    my_string = (char *) malloc (buffersize * sizeof(char));
    charsRead = getline (&my_string, &buffersize, stream_f1);

    Don't cast the return of malloc and I'm sure getline takes a char*, not char*[x].
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  4. #4
    Registered User
    Join Date
    May 2008
    Posts
    16
    dwks, Thanks. Yes, I'm trying to get a numerical value out of the string, otherwise I have to have 30 'else if' statements... which just seems ridiculous to me. So I want to maybe be able to convert it so I can use a for loop to increment from 01 to 31 so I save myself a ton of code.

    and the only reason I have the do statements is just to group them together. I'm gonna have a statement later on to print the formatted date (by concatenating the variables from date func) only if those elements all exist together from the given string from 'my_string'... otherwise the function will do nothing, return to main without incrementing i.

    I know it's kinda hacked together, but since my experience and understanding is limited, it was one of the only ways I could think to do it.

    And Elysia, I tried to assign my_string as simply "char *"... but it didn't seem to work. If you comment out the date function, the program works fine (copies input to output with url_func() separating as the first elemented to be printed.
    I do need to tweak how that works a bit, because it's not doing exactly what I want it to, and doesn't take into account certain scenarios of how the unformatted text might be printed.

    Anyways, thanks for the replies. Any other advice on this would be greatly appreciated.

  5. #5
    Registered User
    Join Date
    May 2008
    Posts
    16
    Btw, dwks... just started looking at this:
    http://www.manpagez.com/man/3/regex/

    Thanks very much for the link. This looks like it should be very helpful for what I'm trying to do.

  6. #6
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,048
    I think that perhaps this will be helpful as well:

    To convert a number to a string, use sprintf().
    Code:
    char buffer[SIZE];
    int number = 3;
    sprintf(buffer, "&#37;d", number);
    
    printf("%s\n", buffer);
    To convert a string to a number (which looks more like what you're doing), you can use strtol() or sscanf().
    Code:
    const char *string = "123";
    int number;
    sscanf(string, "%d", &number);
    sscanf() returns the number of items it successfully read. Since there's just one item being read here ("%d"), it will return 1 upon success. I suggest you check for this value. (It could return 0 on error, or perhaps EOF. It's safest to just compare against 1.)

    For code like your weekday code, consider something like this:
    Code:
    const char *look[] = {"Mon", "Tues", "Wed", /* ... */ };
    const
    size_t x;
    
    for(x = 0; x < sizeof(look)/sizeof(*look); x ++) {
        if(strstr(some_string, look[x])) {
            printf("%s\n", look[x]);
        }
    }
    Note here that strstr() returns a pointer to the string it found. I basically converted your if statements into one loop . . . .

    And the case-insensitive strstr() that I promised:
    Code:
    #include <stdio.h>
    #include <ctype.h>
    
    const char *insensitive_strstr(const char *inside, const char *find) {
        const char *start;
        size_t pos;
        
        for(start = inside; *start; start ++) {
            for(pos = 0; find[pos]; pos ++) {
                if(tolower(start[pos]) != tolower(find[pos])) break;
            }
            
            if(!find[pos]) return start;
        }
        
        return 0;
    }
    
    int main() {
        printf("\"e\" in \"hello\": %s\n", insensitive_strstr("hello", "e"));
        printf("\"xxf\" in \"xxXffm\": %s\n", insensitive_strstr("xxXffm", "xxf"));
        
        return 0;
    }
    I actually think that your whole problem could be solved using sscanf() . . . something like this.
    Code:
    const char *date = "Mon June 10";
    char mday[SIZE], month[SIZE];
    int wday;
    sscanf(date, "%s%s%d", mday, month, &wday);
    Finally, there are tons of very useful time-related functions in time.h. http://www.cplusplus.com/reference/clibrary/ctime/
    Start with localtime(). It can give you this. http://www.cplusplus.com/tm
    Code:
    time_t t;
    struct tm tm;
    time(&t);
    tm = localtime(&t);
    Hopefully something in that will be useful . . . .
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  7. #7
    Registered User
    Join Date
    May 2008
    Posts
    16
    dwks.... Thank you so much.

    *runs back to emacs

  8. #8
    Registered User
    Join Date
    May 2008
    Posts
    16
    Quote Originally Posted by dwks View Post
    I think that perhaps this will be helpful as well:

    I actually think that your whole problem could be solved using sscanf() . . . something like this.
    Code:
    const char *date = "Mon June 10";
    char mday[SIZE], month[SIZE];
    int wday;
    sscanf(date, "%s%s%d", mday, month, &wday);

    The only problem with this, is I don't know how exactly the date will be formatted since it will be coming from a variety of sources. For example, it could be printed:
    "Monday, January 1, 2008" or "01 Mon Jan 2008" etc. etc...

    So I figured it would be better to isolate the components, given the potential variance.

    Thanks again, going through and checking your other suggestions now.

  9. #9
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,048
    In that case, I have one other suggestion: break your string up into words. Then you can look at each word -- if it's "Mon" or "Monday", you have a day; if it's "Jan" or "January", it's a month; if you can't figure out what it is, but sscanf() can convert it to a number, then it must be a (numerical) day (unless it's four digits long, in which case it's a year) . . . .

    If you wanted to try something like that, consider strtok(), with delimiters like " ,". Or you could write your own.

    One thing you really should consider using, though, is this:
    Code:
    int number;
    if(sscanf(string, "&#37;d", &number) == 1) {
        /* it's a number, stored in number */
    }
    else {
        /* it's not a number */
    }
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Custom String class gives problem with another prog.
    By I BLcK I in forum C++ Programming
    Replies: 1
    Last Post: 12-18-2006, 03:40 AM
  2. Program using classes - keeps crashing
    By webren in forum C++ Programming
    Replies: 4
    Last Post: 09-16-2005, 04:58 PM
  3. class object manipulation
    By guda in forum C++ Programming
    Replies: 2
    Last Post: 10-09-2004, 11:43 AM
  4. string handling
    By lessrain in forum C Programming
    Replies: 3
    Last Post: 04-24-2002, 08:36 PM
  5. string manipulation
    By SPEKTRUM in forum Linux Programming
    Replies: 3
    Last Post: 01-26-2002, 11:41 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21