472,780 Members | 1,811 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,780 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 5811
<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: Rina0 | last post by:
Cybersecurity engineering is a specialized field that focuses on the design, development, and implementation of systems, processes, and technologies that protect against cyber threats and...
0
linyimin
by: linyimin | last post by:
Spring Startup Analyzer generates an interactive Spring application startup report that lets you understand what contributes to the application startup time and helps to optimize it. Support for...
0
by: erikbower65 | last post by:
Here's a concise step-by-step guide for manually installing IntelliJ IDEA: 1. Download: Visit the official JetBrains website and download the IntelliJ IDEA Community or Ultimate edition based on...
0
by: Taofi | last post by:
I try to insert a new record but the error message says the number of query names and destination fields are not the same This are my field names ID, Budgeted, Actual, Status and Differences ...
14
DJRhino1175
by: DJRhino1175 | last post by:
When I run this code I get an error, its Run-time error# 424 Object required...This is my first attempt at doing something like this. I test the entire code and it worked until I added this - If...
0
by: Rina0 | last post by:
I am looking for a Python code to find the longest common subsequence of two strings. I found this blog post that describes the length of longest common subsequence problem and provides a solution in...
5
by: DJRhino | last post by:
Private Sub CboDrawingID_BeforeUpdate(Cancel As Integer) If = 310029923 Or 310030138 Or 310030152 Or 310030346 Or 310030348 Or _ 310030356 Or 310030359 Or 310030362 Or...
0
by: lllomh | last post by:
Define the method first this.state = { buttonBackgroundColor: 'green', isBlinking: false, // A new status is added to identify whether the button is blinking or not } autoStart=()=>{
0
by: lllomh | last post by:
How does React native implement an English player?

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.