473,769 Members | 7,272 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

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(c har)*(count+1)) ;
*c = count+1;

while(end<lengt h) {
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 5908
<vi*******@gmai l.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(c har)*(count+1)) ;
*c = count+1;

while(end<lengt h) {
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*******@gmai l.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(c har)*(count+1)) ;
you want (count + 1) * sizeof(char *).
It is an array of pointers, not of chars.
>
*c = count+1;

while(end<lengt h) {
*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*******@gmai l.comha scritto nel messaggio
news:11******** **************@ y66g2000hsf.goo glegroups.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(c har)*(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*******@gmai l.comha scritto nel messaggio
news:11******** **************@ y66g2000hsf.goo glegroups.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(cha r 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(cha r 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@army19 87-laptop:~$ gcc foo.c -ansi -Wall -pedantic
army1987@army19 87-laptop:~$ ./a.out
4
{"This","is","a ","test"}
army1987@army19 87-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********@yah oo.comha scritto nel messaggio
news:46******** *******@yahoo.c om...
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(c har)*(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<lengt h) {
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*******@gmai l.comha scritto nel messaggio
<snip>
> ptr = (char**) malloc(sizeof(c har)*(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

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

Similar topics

9
2738
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 function. example: NOTE: the strings can be of different length and the array will be
7
10927
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. What I would like to do is create an array of strings. More specifically, I would like to create an array of char* 's. And the only catch is that I will need to pass the array by reference to several methods. Although from my understanding...
5
39428
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 in advance, Robert
2
6460
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 "*?<>/\|\\" If one of the chars are found, I'd like to replace it with a "-" and then commit the change to the actual file system. I know that a scripting language may be better suited for this, but I'm experimenting with C and I'm trying to...
23
3613
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
2154
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 which is part of the "atoms" structure that is passed into the function from the outside. I have not yet found where it is allocated but I'm reasonably sure from other chunks of this code that it was by:
24
3461
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 declared an array as: char *stringArray = {"one","two","three","a"}; When I pass the array using:
18
4063
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
4087
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
10216
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, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
9865
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 protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
8873
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
7413
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6675
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5309
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
1
3965
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
3565
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2815
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

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.