string to array

A

Alessio

Hi,

I'm wondering, there's a better way to convert a string into an array ?
Without using an additional pointer ?

//
#include <stdio.h>

//
#define MAX_WORDS 16

//
int main(void)
{
char text[] = "this is a string that I use for an experiment, that
should be work, I hope.";
char *p[MAX_WORDS] = { 0 };

int word_count = 0;
for ( int i = 0; '\0' != text; i++ )
{
if ( 0 == p[word_count] )
{
p[word_count] = &text;
}

if ( ' ' == text )
{
text = '\0';

if ( ++word_count >= MAX_WORDS )
{
printf("string has too many words!\n");

return -1;
}
}
}

++word_count;

for ( int i = 0; i < word_count; i++ )
{
printf("p[%d] = %s\n", i, p);
}

return 0;
}

Thanks.
 
S

Spiros Bousbouras

Hi,

I'm wondering, there's a better way to convert a string into an array ?
Without using an additional pointer ?

I'm not sure what you mean "without an additional pointer".
The input string is an array of char and you want to create
an array of pointers to char so by definition you need two
objects where each one must be either an array or a pointer.
//
#include <stdio.h>

//
#define MAX_WORDS 16

//
int main(void)
{
char text[] = "this is a string that I use for an experiment, that
should be work, I hope.";
char *p[MAX_WORDS] = { 0 };

int word_count = 0;
for ( int i = 0; '\0' != text; i++ )
{
if ( 0 == p[word_count] )
{
p[word_count] = &text;
}

if ( ' ' == text )
{
text = '\0';

if ( ++word_count >= MAX_WORDS )
{
printf("string has too many words!\n");

return -1;
}
}
}

++word_count;

for ( int i = 0; i < word_count; i++ )
{
printf("p[%d] = %s\n", i, p);
}

return 0;

}


If text[] contains successive spaces you get empty words.
Is this what you want? If the last character of text[] is a
space then p[word_count-1] is NULL which you pass to
printf causing undefined behavior.
 
J

jfbode1029

Hi,

I'm wondering, there's a better way to convert a string into an array ?
Without using an additional pointer ?

//
#include <stdio.h>

//
#define MAX_WORDS       16

//
int main(void)
{
        char text[] = "this is a string that I use for an experiment, that
should be work, I hope.";
        char *p[MAX_WORDS] = { 0 };

        int word_count = 0;
        for ( int i = 0; '\0' != text; i++ )
        {
                if ( 0 == p[word_count] )
                {
                        p[word_count] = &text;
                }

                if ( ' ' == text )
                {
                        text = '\0';

                        if ( ++word_count >= MAX_WORDS )
                        {
                                printf("string has too many words!\n");

                                return -1;
                        }
                }
        }

        ++word_count;

        for ( int i = 0; i < word_count; i++ )
        {
                printf("p[%d] = %s\n", i, p);
        }

        return 0;

}

Thanks.


Read up on strtok() and strspn().

Using strtok():

#include <string.h>
#include <stdio.h>

#define MAX_WORDS 16

int main(void)
{
char text[] = "this is a string that I use for an experiment,"
" that should be work, I hope.";
char *p[MAX_WORDS] = { 0 };
int word_count = 0;
int i;

char *tmp = strtok(text, " \t\n");
while (tmp && word_cout < MAX_WORDS)
{
p[word_count++] = tmp;
tmp = strtok(NULL, " \t\n");
}

if (word_count == MAX_WORDS)
printf("Too many words\n");

for (i = 0; i < word_count; i++)
printf("p[%d] = %s\n", i, p);

return 0;
}
 
S

s0suk3

Hi,

I'm wondering, there's a better way to convert a string into an array ?
Without using an additional pointer ?

<snip>

In addition to the problems mentioned by Spiros (empty words on
successive spaces), you also modify the string to be examined, which
often isn't feasible in more realistic situations.

The following function deals with both problems, and returns a argv-
style array of malloc'ed strings (the array itself is also malloc'ed):

char** stringToArray(const char* s)
{
int count = 0;
const char* start = s;
const char* end;
#define WHITESPACE " \f\n\r\t\v"
while ((end = strpbrk(start, WHITESPACE))) {
if (end != start)
++count;
start = end + 1;
}
if (strlen(start) > 0)
++count;

char** result = malloc(sizeof(char*) * (count + 1));
if (!result)
return 0;

int i = 0;
start = s;
while ((end = strpbrk(start, WHITESPACE))) {
if (end != start) {
result = malloc(end - start + 1);
if (!result) {
for (int j = 0; j < i; ++j)
free(result[j]);
free(result);
return 0;
}
strncpy(result, start, end - start);
result[i++][end - start] = '\0';
}
start = end + 1;
}

size_t len = strlen(start);
if (len > 0) {
result = malloc(len + 1);
if (!result) {
for (int j = 0; j < i; ++j)
free(result[j]);
free(result);
return 0;
}
strcpy(result, start);
++i;
}

result = 0;
return result;
}

Sebastian
 
C

CBFalconer

Alessio said:
I'm wondering, there's a better way to convert a string into an
array ? Without using an additional pointer ?

No need. A C string IS an array of char, with a terminating '\0'.
 
F

Franken Sense

In Dread Ink, the Grave Hand of Richard Heathfield Did Inscribe:
CBFalconer said:


More specifically, a C string is a sequence of contiguous characters
terminated by the first null character. It need not be an array. To
take a rather extreme example, the following code is legal (albeit
rather odd):

#include <stdio.h>

int main(void)
{
char null = 0;
printf("%s\n", &null);
return 0;
}

I wasn't expecting this output:

http://lomas-assault.net/usenet/z32.jpg
--
Frank

The biases the media has are much bigger than conservative or liberal.
They're about getting ratings, about making money, about doing stories that
are easy to cover.
~~ Al Franken,
 
B

BartC

CBFalconer said:
No need. A C string IS an array of char, with a terminating '\0'.

Well, yes (although the terminator comes after the string rather than the
array).

But a quick glance at the rest of the post shows it is actually about
dividing a string into words.

Bart
 
F

Flash Gordon

Franken said:
In Dread Ink, the Grave Hand of Richard Heathfield Did Inscribe:


I wasn't expecting this output:

http://lomas-assault.net/usenet/z32.jpg

The image shows a hex-dump indicating a normal Windows line termination,
i.e. CRLF.

This is the correct output and what you should expect. Of course, on
Unix like systems you will just get the LF.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,777
Messages
2,569,604
Members
45,234
Latest member
SkyeWeems

Latest Threads

Top