Thread: how to break a string into array of strings

  1. #16
    Registered User
    Join Date
    Sep 2001
    Posts
    4,912
    KBrigg's post above tells you how to do that. Keep in mind, however, what Sebastiani pointed out - be careful of multiple consecutive spaces, and spaces at the beginning / end of your string (but you should try and get it working on a simple string first - then get it to handle multiple spaces, etc...)

  2. #17
    Banned
    Join Date
    Oct 2008
    Posts
    1,535
    i tried to use sscanf too

    Code:
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    typedef struct node node;
    struct node{
    	int value;
    	struct node * next;
    };
     int countletters(char *str);
     char * sortbycount(char* str);
    void main()
    {
    	int g;
    	char  str[18]="aabx bXcb bBxaDAa";
    	char * r;
    	g=countletters(str);
    	r=sortbycount(str);
    }
    
    
    int countletters(char *str)
    {
    	int i,cnt=0;
    	int ch[26]={0};
        for (i=0;i<(int)strlen(str);i++)
    	{
           if ((str[i]>='a')&&(str[i]<='z'))
    	   {
              ch[str[i]-'a']=1;
    	   }
    	   if ((str[i]>='A')&&(str[i]<='Z'))
    	   {
              ch[str[i]-'A']=1;
    	   }
    	}
    	for (i=0;i<26;i++)
    	{
    		if(ch[i]==1){ cnt++;}
    	}
    	printf("%d",cnt);
       return cnt;
    }
    
    char * sortbycount(char* str)
    {
      int start=0,t=0,i,cnt=0;char** arr;
      for (i=0;i<(int)strlen(str);i++)
      {
        if (str[i]==' ') cnt++;
      }
      arr=(char**)malloc(sizeof(char*)*(cnt+1));
      i=0;
      do
      {
         for (i=start;str[i]!=' ';i++);
         arr[t]=(char*)malloc(sizeof(char)*(i-start+1));
         sscanf(arr[t],"%s",str+start); 
    	 printf("%s",arr[t]);
    	 start=i;
       t++;
      }while(t<cnt);
      
     return str;
    }
    when i do scanf("%s",str);
    it should stop copying from stdin on enter or space

    correct ?

  3. #18
    Registered User
    Join Date
    Sep 2001
    Posts
    4,912
    No - %s copies a string. A string is a null-terminated array of chars. A space is a character. You should know that by looking at the documentation. You should also know that by having done a small test. Why didn't you write a small program to test that?

  4. #19
    Banned
    Join Date
    Oct 2008
    Posts
    1,535
    i know that there is some command for which %d %s
    stops when there is a space

  5. #20
    Registered User
    Join Date
    Oct 2006
    Posts
    250
    I am really curious, so I decided to write this nonrelevant contribution to the topic at hand: don't you guys have better things to do than waste your time and energy on this guy?

  6. #21
    Registered User
    Join Date
    Sep 2001
    Posts
    4,912
    i know that there is some command for which %d %s
    stops when there is a space
    How do you know that? I'm looking through every reference I can find and I see no such thing. I've also never heard of it before. I'm not saying it doesn't exist, because I could be wrong, but I'm pretty sure you're gonna have to go along the lines of what KBriggs suggested.

    don't you guys have better things to do than waste your time and energy on this guy?
    He should be glad that the project I'm debugging has huge build-times. Though transgalactic2, I'm getting really close to closing this thread- there really isn't anything else anyone can do that will really help you.

  7. #22
    Banned
    Join Date
    Oct 2008
    Posts
    1,535
    there is that thing in fscanf
    [^$] (copy till you get char $)

    but i learned that we dont write in fscanf
    %[^ ]

    but we just write %s or %d
    and it stops on space

    i did that on files

    and it should work too on sscanf

    (append every char is not practical solution in a test ,i dont have so much time)

  8. #23
    Registered User
    Join Date
    Jun 2009
    Posts
    486
    the great thing about writing code is that is takes basically the same amount of human time to do it character by character or by string, since loops are so helpful

    And since string operations in c are such a pain in the ass to get right, you are more likely to get character by character code right if you are writing it on a test anyway. Plus you don't have to deal with all that crap about spaces etc.

    isn't there an example in K&R that deals with this kind of thing?

  9. #24
    Registered User
    Join Date
    Sep 2001
    Posts
    4,912
    You must be referring to this, though I didn't know this existed:
    Matches a nonempty sequence of characters from the specified set of accepted characters; the next pointer must be a pointer to char, and there must be enough room for all the characters in the string, plus a terminating null byte. The usual skip of leading white space is suppressed. The string is to be made up of characters in (or not in) a particular set; the set is defined by the characters between the open bracket [ character and a close bracket ] character. The set excludes those characters if the first character after the open bracket is a circumflex (^). To include a close bracket in the set, make it the first character after the open bracket or the circumflex; any other position will end the set. The hyphen character - is also special; when placed between two other characters, it adds all intervening characters to the set. To include a hyphen, make it the last character before the final close bracket. For instance, [^]0-9-] means the set "everything except close bracket, zero through nine, and hyphen". The string ends with the appearance of a character not in the (or, with a circumflex, in) set or when the field width runs out.
    According to this,
    Code:
    [^ ]
    would exclude everything but the spaces. But I'm not sure that it stops reading when it encounters a space. It almost sounds like it just excludes those characters. Here's an exercise: try it and see which one is true.

  10. #25
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    >> ok so how to do so it will copy into arr[t] till str reaches a space

    Start by fixing all of the other many problems that have already been pointed out to you, to begin with. Come to think of it, what's the point of trying to help you if you're just going to ignore everyones advice, anyway?
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  11. #26
    Registered User ssharish2005's Avatar
    Join Date
    Sep 2005
    Location
    Cambridge, UK
    Posts
    1,732
    I guess that by using sscanf function you can reduce a hell lot of code. To get this job done. But as other said you need to fix other things before youi can get to this point.

    -ssharish
    Life is like riding a bicycle. To keep your balance you must keep moving - Einstein

  12. #27
    Registered User
    Join Date
    Jan 2008
    Posts
    225
    may be this is what you're looking for. but this is not correct way of doing you can reduce lot of code using sscanf as pointed earlier, but just in case

    Code:
    #include <stdio.h>
    
    int main()
    {
     char strInput[80],strFinalWords[10][20];
    
     int intIndex,intLength,intTempCounter = 0,intWordCounter = 0;
    
     printf("Enter Any String :");
     gets(strInput);
     for(intIndex = 0 ; strInput[intIndex] != '\0' ; intIndex++)
     {
    	if(strInput[intIndex] == ' ')
    	{
    		strFinalWords[intWordCounter][intTempCounter] = '\0';
    		if(intIndex > 0 && strInput[intIndex - 1] != ' ')
    		{
    			intTempCounter = 0;
    			intWordCounter++;
    		}
    		continue;
    	}
    	strFinalWords[intWordCounter][intTempCounter] = strInput[intIndex];
    	intTempCounter++;
     }
     strFinalWords[intWordCounter][intTempCounter] = '\0';
    
     for(intIndex = 0 ; intIndex <= intWordCounter ; intIndex++)
    	printf("%s\n",strFinalWords[intIndex]);
    
     return 0;
    }

  13. #28
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    >> may be this is what you're looking for.

    Just keep in mind that the forum policy here is not to do other peoples homework. Try to provide advice - not explicit solutions.
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  14. #29
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Code:
    void foo( char *bar, char **baz, size_t rows, size_t cols )
    {
         size_t x = 0, y = 0;
        while( *bar )
        {
            baz[ y ][ x ] = *bar;
            if( isspace( baz[ y ][ x ] ) || x + 1 == cols )
            {
                baz[ y++ ][ x ] = '\0';
                while( *bar && isspace( *bar++ ) );
                x=0;
            }
            else
            {
                x++;
                bar++;
            }
        }
    }
    I haven't tried it, but that looks about right. If it is, you'll want to actually be able to explain in words what it's doing before you decide to use it as homework. If it's not, you being able to fix it should impress your teacher.

    [edit]
    This one is more fun!
    Code:
    #include<stdio.h>
    #include<ctype.h>
    
    void foo( char *s, char *bar, size_t rows, size_t cols )
    {
        size_t x = -1,y = 0;
        while( s && *s )
        {
            bar[(y=isspace(*s)&&y+1<rows?y+1:y)*cols+(x=isspace(*s)?-
            1:x+1<cols?x+1:x)]=isspace(*s)?'\0':*s;s=y<rows?s+1:NULL;
        }
    }
    
    int main( void )
    {
        char * bar = "hello world";
        char baz[ 2 ][ 10 ] = {{0}};
        
        foo( bar, &baz[0][0], 2, 10 );
    
        printf( "\'%s\' \'%s\'\n", baz[0], baz[1] );
    
        return 0;
    }
    Probably still a good idea to be able to explain it before you turn it in though...
    [/edit]


    Quzah.
    Last edited by quzah; 06-26-2009 at 12:32 AM.
    Hope is the first step on the road to disappointment.

  15. #30
    Registered User
    Join Date
    Mar 2009
    Posts
    344
    From the "it compiles so its fine by me" category :

    Code:
    char **split_str(char *str)
    {
       int words = strlen(str) + 1;
       char **arr = calloc(words, sizeof(*arr));
    
       for (; isspace(*str); str++);
            words = 0;
    
       while (*str)
       {
          arr[!isspace(32)] = str;
          for (arr += 1; *str && !isspace(*str); str++);
             if (*str && !(*str = '\0')) str++;
          for (words += 1; *str && isspace(*str); str++);
       }
    
       return arr - words;
    }
    Unlike the other solutions posted, this doesn't waste space making extra copies of the string. Whether or not that's a good thing is open to debate, though

    Hopefully no one turns this in as homework (or if they do, I hope they get what they deserve) so I think this is within the rules of the forum.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Another syntax error
    By caldeira in forum C Programming
    Replies: 31
    Last Post: 09-05-2008, 01:01 AM
  2. Inheritance Hierarchy for a Package class
    By twickre in forum C++ Programming
    Replies: 7
    Last Post: 12-08-2007, 04:13 PM
  3. ascii rpg help
    By aaron11193 in forum C Programming
    Replies: 18
    Last Post: 10-29-2006, 01:45 AM
  4. Something is wrong with this menu...
    By DarkViper in forum Windows Programming
    Replies: 2
    Last Post: 12-14-2002, 11:06 PM
  5. error with code
    By duffy in forum C Programming
    Replies: 8
    Last Post: 10-22-2002, 09:45 PM