473,397 Members | 2,033 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,397 software developers and data experts.

How to Return an array of strings in C (char**)

I am trying to implement the Split function in C ie.
if i have a string: char* S="This is a test";
and if i try to split based on space ' ' it should return an array of
strings like:

{"This","is","a","test"} .

I tried to implement it as given below but am getting a segmentation
fault. I would really appreciate if some one could give me an answer
on this issue:

char** split(char str[],int*c) {
int start=0;
int end =0 ;
char** temp=NULL;
char** ptr;
int count=0;
int length = strlen(str);
//first counting the number of spaces
// to know the number of elements in the array
while (str) {
if (*str==' ') count++;
}
printf("count value is %d \n",count);
// I am doubt ful about the malloc too
ptr = (char**) malloc(sizeof(char)*(count+1));
*c = count+1;

while(end<length) {
ptr = str + start;
if (str[end]!=' ' || length) {
end++;
}
if (str[end]!='\0') {// replacing spaces with \0
str[end]='\0';
}
if (!temp) temp= ptr;
ptr++;
}
return temp;
}

Thanks

Mar 25 '07 #1
10 5871
<vi*******@gmail.comwrote:
>I am trying to implement the Split function in C ie.
if i have a string: char* S="This is a test";
and if i try to split based on space ' ' it should return an array of
strings like:

{"This","is","a","test"} .

I tried to implement it as given below but am getting a segmentation
fault. I would really appreciate if some one could give me an answer
on this issue:

char** split(char str[],int*c) {
int start=0;
int end =0 ;
char** temp=NULL;
char** ptr;
int count=0;
int length = strlen(str);
//first counting the number of spaces
// to know the number of elements in the array
while (str) {
if (*str==' ') count++;
}
printf("count value is %d \n",count);
// I am doubt ful about the malloc too
ptr = (char**) malloc(sizeof(char)*(count+1));
*c = count+1;

while(end<length) {
ptr = str + start;
if (str[end]!=' ' || length) {
end++;
}
if (str[end]!='\0') {// replacing spaces with \0
str[end]='\0';
}
if (!temp) temp= ptr;
ptr++;
}
return temp;
}
I am not a fan of coding where the malloc and free are in different
functions unless there is a good reason to do so. So I would not return
anything (return void) from split: have the caller allocate the space, tell
split where the space is, modify it in place and have the caller be
responsible for doing the free. If this is a learning exercise, you will
have to make the array you are trying to return static. I hope the
information you need to continue is in the link to the FAQ, if not post
another question.

http://c-faq.com/~scs/cgi-bin/faqcat.cgi?sec=aryptr
Mar 25 '07 #2

<vi*******@gmail.comwrote in message
>I am trying to implement the Split function in C ie.
if i have a string: char* S="This is a test";
and if i try to split based on space ' ' it should return an array of
strings like:

{"This","is","a","test"} .

I tried to implement it as given below but am getting a segmentation
fault. I would really appreciate if some one could give me an answer
on this issue:

char** split(char str[],int*c) {
int start=0;
int end =0 ;
char** temp=NULL;
char** ptr;
int count=0;
int length = strlen(str);
This must be where you crashed, if you cut and pasted this code. The input
must be null or not set up correctly.
>
//first counting the number of spaces
// to know the number of elements in the array
while (str) {
if (*str==' ') count++;
}
The reason is that you fail to increment str. Unless input is an empty
string, this will run forever. Since the program didn't hang, probably the
crash was above.
>
printf("count value is %d \n",count);
// I am doubt ful about the malloc too
ptr = (char**) malloc(sizeof(char)*(count+1));
you want (count + 1) * sizeof(char *).
It is an array of pointers, not of chars.
>
*c = count+1;

while(end<length) {
*ptr = str + start.
ptr = str + start;
What is length doing in this condition ?
if (str[end]!=' ' || length) {
end++;
}
this should surely be an else if.
if (str[end]!='\0') {// replacing spaces with \0
str[end]='\0';
Now you need to set *ptr to str + start. You also need to update start, and
increment end.
{
This confused me. Much better to set temp before entering the loop.
if (!temp) temp= ptr;
ptr++;
}
return temp;
}

Thanks
Its nearly there. Generally the way to debug rotuintes like this is to slip
in diagnostic printfs. For instance you could have printfed your input
printf("***%s***\n", str) to see it was valid. The asterisks are there to
pick up any funny spaces. The you could have printed "here" before entering
the main loop to see if you actually got there, then str + start to see
where you go to in the string on each pass.

Mar 25 '07 #3
vi*******@gmail.com wrote:
>
I am trying to implement the Split function in C ie.
if i have a string: char* S="This is a test";
and if i try to split based on space ' ' it should return
an array of strings like:

{"This","is","a","test"} .

I tried to implement it as given below but am getting a
segmentation fault. I would really appreciate if some one
could give me an answer on this issue:
Search the google archives for my posting of "toksplic.c".

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>

--
Posted via a free Usenet account from http://www.teranews.com

Mar 25 '07 #4

<vi*******@gmail.comha scritto nel messaggio
news:11**********************@y66g2000hsf.googlegr oups.com...
>I am trying to implement the Split function in C ie.
if i have a string: char* S="This is a test";
and if i try to split based on space ' ' it should return an array of
strings like:

{"This","is","a","test"} .

I tried to implement it as given below but am getting a segmentation
fault. I would really appreciate if some one could give me an answer
on this issue:
[snip]
while (str) {
if (*str==' ') count++;
}
You meant *str++, didn't you?
ptr = (char**) malloc(sizeof(char)*(count+1));
Unless you have 256 bytes of memory (or some system with CHAR_BIT 8) a
pointer to char will be definitely larger than a char.
if (!temp) temp= ptr;
When did you exactly use temp after initializing it to NULL?
Mar 25 '07 #5

<vi*******@gmail.comha scritto nel messaggio
news:11**********************@y66g2000hsf.googlegr oups.com...
>I am trying to implement the Split function in C ie.
if i have a string: char* S="This is a test";
and if i try to split based on space ' ' it should return an array of
strings like:

{"This","is","a","test"} .

I tried to implement it as given below but am getting a segmentation
fault. I would really appreciate if some one could give me an answer
on this issue:

char** split(char str[],int*c) {
[snip]
}
That's way too long for my standards, I'd use several functions.

/* BEGIN foo.c */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int count_char(char c, char *str);
int search_char(char c, char *str);

char **split(char *str, int *c)
{
int i, wlen;
int num = count_char(' ', str) + 1;
char **res = malloc(num * sizeof(char *));
*c = num;
if (res == NULL) {
perror("Unable to allocate memory");
return NULL;
}
for (i=0; i<num; i++) {
wlen = (i<num-1) ? search_char(' ', str) : strlen(str);
res[i] = malloc(wlen + 1);
if (res[i] == NULL) {
perror("Unable to allocate memory");
return NULL;
}
strncpy(res[i], str, wlen);
res[i][wlen] = '\0';
str += wlen + 1;
}
return res;
}

int count_char(char c, char *str)
{
int i, res = 0;
for (i=0; str[i] != '\0'; i++)
if (str[i] == c) res++;
return res;
}

int search_char(char c, char *str)
{
int i;
for (i=0; str[i] != '\0'; i++)
if (str[i] == c) return i;
return -1; /* c not found in str */
}

int main(void)
{
int i, n;
char **a = split("This is a test", &n);
printf("%d\n{", n);
for (i=0; i<n; i++)
printf("\"%s\",", a[i]);
puts("\b}");
return 0;
}

/* END foo.c */

army1987@army1987-laptop:~$ gcc foo.c -ansi -Wall -pedantic
army1987@army1987-laptop:~$ ./a.out
4
{"This","is","a","test"}
army1987@army1987-laptop:~$

(Anyway, in the if (res[i] == NULL) within the for loop in function split
I'd better free res[0], res[1], ... res[i-1] and res, and assign NULL to
res.)


Mar 25 '07 #6

"Army1987" <pl********@for.itha scritto nel messaggio
news:eu**********@tdi.cu.mi.it...
(Anyway, in the if (res[i] == NULL) within the for loop in function split
I'd better free res[0], res[1], ... res[i-1] and res, and assign NULL to
res.)
The last point of which is useless anyway, as res is local to split().
Mar 25 '07 #7

"CBFalconer" <cb********@yahoo.comha scritto nel messaggio
news:46***************@yahoo.com...
vi*******@gmail.com wrote:
Search the google archives for my posting of "toksplic.c".
The only one it finds is this one I'm replying to.
Mar 25 '07 #8
On 25 Mar 2007 07:40:02 -0700, vi*******@gmail.com wrote:
>I am trying to implement the Split function in C ie.
if i have a string: char* S="This is a test";
and if i try to split based on space ' ' it should return an array of
strings like:
If your code in the calling function really uses a char* that points
to a literal string, change it to use an array. Your function tries
to modify the string that is passed in and you are not allowed to
modify a string literal.
>
{"This","is","a","test"} .

I tried to implement it as given below but am getting a segmentation
fault. I would really appreciate if some one could give me an answer
on this issue:
You really should sit down with a piece of paper and desk check your
code by pretending to be the computer and manually performing each
step.
>
char** split(char str[],int*c) {
Unless you want to commit the exceptions to memory, you should avoid
any user defined function or object name beginning with str.
int start=0;
int end =0 ;
char** temp=NULL;
char** ptr;
int count=0;
int length = strlen(str);
//first counting the number of spaces
// to know the number of elements in the array
while (str) {
if (*str==' ') count++;
This will count consecutive spaces as if each bounded a word.
}
printf("count value is %d \n",count);
// I am doubt ful about the malloc too
ptr = (char**) malloc(sizeof(char)*(count+1));
Wrong on multiple counts:

Don't cast the return from malloc. It never helps and can cause
the compiler to suppress a diagnostic you would really want to see.
Did you #include stdlib.h. If not this invokes undefined behavior.

ptr is a char**. Therefore, whatever it points to is a char*. On
most systems, sizeof (char*) is a multiple of 4. However, you are
using sizeof (char) which is guaranteed to be 1. You are not
allocating enough space by at least 75%. Rather than go through the
mental gymnastics of keeping the types straight in your head, let the
compiler do it for you with
ptr = malloc((count+1) * sizeof (*ptr));
This will work for any type of ptr except void*.

You should always check malloc for success.
*c = count+1;
All of your count+1 terms seem wrong.
>
while(end<length) {
ptr = str + start;
Didn't your compiler give you a diagnostic here? ptr is a char**. str
is char*. The expression str+start also has type char*. There is no
implicit conversion between the two.

What happened to the memory you just allocated? Who points to it? Do
str or start ever change values?

What you really want is
start = end;
here.
if (str[end]!=' ' || length) {
If length is positive, this always evaluates to true. Make sure you
understand why. You probably meant
if (str[end] != ' ' && end < length) {
Make sure you understand why && and not ||.
end++;
}
if (str[end]!='\0') {// replacing spaces with \0
str[end]='\0';
You need to increment end so the next iteration through the loop does
not start on the '\0' you just inserted.
}
if (!temp) temp= ptr;
This should be done unconditionally right after the malloc.
ptr++;
What you really want here is
*ptr++ = &str[start];
Now figure out why.
}
return temp;
}

Remove del for email
Mar 25 '07 #9
Army1987 wrote, On 25/03/07 22:18:
<vi*******@gmail.comha scritto nel messaggio
<snip>
> ptr = (char**) malloc(sizeof(char)*(count+1));
Unless you have 256 bytes of memory (or some system with CHAR_BIT 8) a
pointer to char will be definitely larger than a char.
Which is why we generally recommend using the form
ptr = malloc(N * sizeof *ptr);
Note the lack of a cast, since casts can hide the serious error of not
including stdlib.h, and using sizeof *ptr so you don't have to worry
about getting the type right.
--
Flash Gordon
Mar 25 '07 #10
Army1987 wrote:
"CBFalconer" <cb********@yahoo.comha scritto nel messaggio
>Search the google archives for my posting of "toksplic.c".

The only one it finds is this one I'm replying to.
That should be toksplit.c

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>
--
Posted via a free Usenet account from http://www.teranews.com

Mar 26 '07 #11

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

9
by: Rafi Kfir | last post by:
Hi, This may look as a smiple task to most of you, but to me (a beginner with C), it drives me crazy. All I want is that one function passes a two dimensional array of strings to another...
7
by: Ben | last post by:
Hey everybody, I'm working on a program in c++, and I've come up against a problem that I can't figure out. I don't imagine that it's too difficult to solve, but it has been giving me trouble....
5
by: Robert | last post by:
Hi, Is there some way of using an array of strings? Like in basic? I know you have to create an array of chars so i think it has to be an 2d array or something... Really stuck here... Thanks...
2
by: hokieghal99 | last post by:
I wish to place all files and directories that are within a user defined path (on a Linux x86 PC) into some type of array and then examine those items for the existence of certain charaters such as...
23
by: Nascimento | last post by:
Hello, How to I do to return a string as a result of a function. I wrote the following function: char prt_tralha(int num) { int i; char tralha;
3
by: David Mathog | last post by:
This one is driving me slightly batty. The code in question is buried deep in somebody else's massive package but it boils down to this, two pointers are declared, the first is: char **resname...
24
by: Michael | last post by:
Hi, I am trying to pass a function an array of strings, but I am having trouble getting the indexing to index the strings rather than the individual characters of one of the strings. I have...
18
by: Pedro Pinto | last post by:
Hi there once more........ Instead of showing all the code my problem is simple. I've tried to create this function: char temp(char *string){ alterString(string); return string;
14
by: Shhnwz.a | last post by:
Hi, I am in confusion regarding jargons. When it is technically correct to say.. String or Character Array.in c. just give me your perspectives in this issue. Thanx in Advance.
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.