Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > how to store strings of any length into an array of type char*?

Reply
Thread Tools

how to store strings of any length into an array of type char*?

 
 
arkobose@gmail.com
Guest
Posts: n/a
 
      05-15-2005
my earlier post titled:
"How to input strings of any lengths into arrays of type: char
*array[SIZE] ?"
seems to have created a confusion. therefore i paraphrase my problem
below.

consider the following program:
#include<stdio.h>
#define SIZE 1
int main()
{
char *array[SIZE];
scanf("%s", array[0]); // type a string of any length whatsoever.
for(int i = 0; *(array[0] + i) != '\0'; i++)
printf("%c", *(array[0] + i));
return 0;
}

when you run this program, you will find that the "printf" outputs the
whole string which you entered through "scanf", no matter how long your
string was.

now suppose you change the constant SIZE to some bigger value, 4, for
example, and then modify the program to this:

#include<stdio.h>
#define SIZE 4

int main()
{
char *array[SIZE] = {"string of any size", "type",
"praetertranssubstantiationali*stically", "another string"};
for(int i = 0; i < SIZE; i++){
for(int j = 0; *(array[i] + j) != '\0'; j++){
printf("%c", *(array[i] + j));
}
printf("\n");
}
return 0;
}

then this program will output the strings with which the array has been
initialized exactly.

but if you want that the strings be entered at run time by user, rather
than be given at initialization as above, then how do you do this?
that is, during execution you type your strings one by one and they get
stored exactly as in the above program.

any ideas?
-arko

 
Reply With Quote
 
 
 
 
Walter Roberson
Guest
Posts: n/a
 
      05-15-2005
In article <(E-Mail Removed). com>,
<(E-Mail Removed)> wrote:
>consider the following program:
>#include<stdio.h>
>#define SIZE 1
>int main()
>{
>char *array[SIZE];
>scanf("%s", array[0]); // type a string of any length whatsoever.
>for(int i =3D 0; *(array[0] + i) !=3D '\0'; i++)
>printf("%c", *(array[0] + i));
>return 0;
>}


>when you run this program, you will find that the "printf" outputs the
>whole string which you entered through "scanf", no matter how long your
>string was.


It doesn't even compile on my C89 compiler.

If I compile it with gcc --std=c99 then it coredumps if I enter
even one character of input.

Purify complains about an uninitialized memory read. That's not
surprising, as you are passing in the -content- of array[0], which
you have not initialized.

When I put in input, Purify then complains about Null Pointer Write.
That's because it -happened- that array[0] had the value 0
(which happens to be the NULL pointer on my system), so when you
write to that buffer via the scanf() call, it tries to write to NULL.
That in turn triggers a COR, coredump because of a SIGSEGV
(Segmentation Violation.)


I didn't bothere to read the rest of your question, as it was
predicated upon the truth of your program functioning properly,
which it absolutely does not do.
--
Entropy is the logarithm of probability -- Boltzmann
 
Reply With Quote
 
 
 
 
arkobose@gmail.com
Guest
Posts: n/a
 
      05-15-2005
dear walter,
the programs which i have posted run absolutely correctly on my
Turboc++ IDE compiler.
if you don't mind giving me your email id, then i can send you both the
source code and the .exe file. you can see for yourself.
-arko

 
Reply With Quote
 
Walter Roberson
Guest
Posts: n/a
 
      05-15-2005
In article <(E-Mail Removed). com>,
<(E-Mail Removed)> wrote:
>dear walter,
>the programs which i have posted run absolutely correctly on my
>Turboc++ IDE compiler.


*Sigh.*

>if you don't mind giving me your email id, then i can send you both the
>source code and the .exe file. you can see for yourself.


I don't think so. I already explained the problems with the code,
and was echoed by another poster.

Re-read the documentation for scanf(). What are the values
that you pass in after the format? Addresses, right? And you
are passing the -content- of array[0] as the address, right?
Now, what is that -content-? Did you initialize array[0] ?
If not, then how do you know what the value will be? Is there
any rule in the C standard that controls what the value is
of variables of "automatic" storage if you do not explicitly
initialize them? If so, then what is the default value, and
what leads you to think that it will happen to be the location
of a chunk of storage which is indefinitely long? If there is
no default value for automatic variables, then what leads you
to think that the random value that happens to be there will be
the location of a chunk of storage which is indefinitely long?
--
Feep if you love VT-52's.
 
Reply With Quote
 
Michael Mair
Guest
Posts: n/a
 
      05-15-2005
http://www.velocityreviews.com/forums/(E-Mail Removed) wrote:
> my earlier post titled:
> "How to input strings of any lengths into arrays of type: char
> *array[SIZE] ?"
> seems to have created a confusion. therefore i paraphrase my problem
> below.


No, the problem is that you do not understand the answers given
to you. This is no insult, just a matter of fact.
You have an understanding problem with the concepts of arrays,
pointers and strings in C.

> consider the following program:
> #include<stdio.h>
> #define SIZE 1
> int main()
> {
> char *array[SIZE];


array is an array of SIZE elements of type char*.
char* is a type that can hold the address of an object of
type char. As it is, the SIZE elements of array are
uninitialised.
If you want to store something through a pointer, then
this pointer must point to storage you own which is also
of the respective type, i.e. to use array[0], it has to
to contain the address of ("point to")
a) a single char
b) the "first" char of an array of char (*)
c) the "start" of a malloc()ed storage region with
effective type char.

This means
a)
char c = 42;
array[0] = &c; /* *array[0] == 42 */
b)
char s[42];
array[0] = s; /* equiv. array[0] = &s[0] */
c)
array[0] = malloc(sizeof *array[0] * 42);
if (array[0] == NULL)
{
/* handle memory trouble */
....
}

> scanf("%s", array[0]); // type a string of any length whatsoever.


You did none of the above.
You just have used the arbitrary bit pattern found at &array[0]
as if it were an address.
If you cleanly initialise array[0] to NULL, you will
see what we all are talking about.

> for(int i = 0; *(array[0] + i) != '\0'; i++)
> printf("%c", *(array[0] + i));
> return 0;
> }
>
> when you run this program, you will find that the "printf" outputs the
> whole string which you entered through "scanf", no matter how long your
> string was.


I bet you that if you throw in a large enough file redirected
to stdin that you will get a segfault/access violation.


> now suppose you change the constant SIZE to some bigger value, 4, for
> example, and then modify the program to this:
>
> #include<stdio.h>
> #define SIZE 4
>
> int main()
> {
> char *array[SIZE] = {"string of any size", "type",
> "praetertranssubstantiationali*stically", "another string"};


Now you initialised array[0] through array[3] to point to
a string literal each.
They could, for example, hold the addresses 4, 7456, 900000,
and 28.

> for(int i = 0; i < SIZE; i++){
> for(int j = 0; *(array[i] + j) != '\0'; j++){
> printf("%c", *(array[i] + j));
> }
> printf("\n");
> }
> return 0;
> }
>
> then this program will output the strings with which the array has been
> initialized exactly.
>
> but if you want that the strings be entered at run time by user, rather
> than be given at initialization as above, then how do you do this?
> that is, during execution you type your strings one by one and they get
> stored exactly as in the above program.


exactly in the way described to you by Chuck, Malcolm, me and maybe
others.
Get yourself some storage to point to and be done.
Reread their answers and have a look at sections 6 and 8 of the
c.l.c FAQ, available from
http://www.eskimo.com/~scs/C-faq/top.html
(maybe also 4, 5)


Cheers
Michael

----
(*) It is of course also possible to set the pointer _not_
to the beginning, e.g.
b)
char s[42];
array[0] = &s[1]; /* equiv. ....= s + 1 */
c)
char *ptr = malloc(sizeof *ptr * 45;
array[0] = ptr[42];
array[1] = ptr[142];
--
E-Mail: Mine is an /at/ gmx /dot/ de address.
 
Reply With Quote
 
Quentarez
Guest
Posts: n/a
 
      05-15-2005
On 15 May 2005 12:03:48 -0700, (E-Mail Removed) wrote:

> my earlier post titled:
> "How to input strings of any lengths into arrays of type: char
> *array[SIZE] ?"
> seems to have created a confusion. therefore i paraphrase my problem
> below.
>
> consider the following program:
> #include<stdio.h>
> #define SIZE 1
> int main()
> {
> char *array[SIZE];
> scanf("%s", array[0]); // type a string of any length whatsoever.
> for(int i = 0; *(array[0] + i) != '\0'; i++)
> printf("%c", *(array[0] + i));
> return 0;
> }
>
> when you run this program, you will find that the "printf" outputs the
> whole string which you entered through "scanf", no matter how long your
> string was.
>
> now suppose you change the constant SIZE to some bigger value, 4, for
> example, and then modify the program to this:
>
> #include<stdio.h>
> #define SIZE 4
>
> int main()
> {
> char *array[SIZE] = {"string of any size", "type",
> "praetertranssubstantiationali*stically", "another string"};
> for(int i = 0; i < SIZE; i++){
> for(int j = 0; *(array[i] + j) != '\0'; j++){
> printf("%c", *(array[i] + j));
> }
> printf("\n");
> }
> return 0;
> }
>
> then this program will output the strings with which the array has been
> initialized exactly.
>
> but if you want that the strings be entered at run time by user, rather
> than be given at initialization as above, then how do you do this?
> that is, during execution you type your strings one by one and they get
> stored exactly as in the above program.
>
> any ideas?
> -arko


I highly recommend you read the excellent page "Getting Data from an Input
Stream" written by Richard Heathfield. It can be found at:
http://www.cognitiveprocess.com/~rjh.../fgetdata.html

-Quentarez
 
Reply With Quote
 
arkobose@gmail.com
Guest
Posts: n/a
 
      05-18-2005
o.k
i solved the problem using an array of the following type:
char *array[SIZE][1];
for any defined value of constant SIZE, i was able to store arbitrary
length strings (o.k, i won't stick to "indefinite length strings").
i hope it works on your compiler!

-arko

 
Reply With Quote
 
Walter Roberson
Guest
Posts: n/a
 
      05-18-2005
In article <(E-Mail Removed) .com>,
<(E-Mail Removed)> wrote:
>i solved the problem


You didn't quote enough context to say which problem. You had at
least 3 different problems with the first program you posted,
and we don't know which of the 3 problems you are referring to.

>using an array of the following type:
> char *array[SIZE][1];
>for any defined value of constant SIZE, i was able to store arbitrary
>length strings


I suggest you post your modified sample code, along with an
description of what you think it is doing. Considering the
solution you have posted, I am suspicious that you have merely
traded one undefined behaviour for another.
--
"[...] it's all part of one's right to be publicly stupid." -- Dave Smey
 
Reply With Quote
 
arkobose@gmail.com
Guest
Posts: n/a
 
      05-18-2005
here's a sample code:

int main()
{
char *array[SIZE][1];

for(int i = 0; i < SIZE; i++)
gets(a[i][0]);

for(i = 0; i < SIZE; i++){
for(int j = 0; *(a[i][0] + j) != '\0'; j++)
printf("%c", *(a[i][0] + j));
printf("\n");
}
return 0;
}
when one enters strings (which may contain white spaces) one by one (of
course, one has to define the constant SIZE first) then the program
prints all the different strings of different lengths (the maximum
length of any string is not specified in the code, and this is the
point) one after another.
a word of caution, though. this code runs fine on my Turbo C++ IDE
(version 3.0) compiler but not on my Turbo C++ (version 4.5) compiler.
so, yes, it may not run on all compilers.

-arko

 
Reply With Quote
 
CBFalconer
Guest
Posts: n/a
 
      05-18-2005
(E-Mail Removed) wrote:
>
> here's a sample code:
>
> int main()
> {
> char *array[SIZE][1];
>
> for(int i = 0; i < SIZE; i++)
> gets(a[i][0]);
>
> for(i = 0; i < SIZE; i++){
> for(int j = 0; *(a[i][0] + j) != '\0'; j++)
> printf("%c", *(a[i][0] + j));
> printf("\n");
> }
> return 0;
> }
> when one enters strings (which may contain white spaces) one by
> one (of course, one has to define the constant SIZE first) then
> the program prints all the different strings of different lengths
> (the maximum length of any string is not specified in the code,
> and this is the point) one after another.
> a word of caution, though. this code runs fine on my Turbo C++
> IDE (version 3.0) compiler but not on my Turbo C++ (version 4.5)
> compiler. so, yes, it may not run on all compilers.


I have no idea what you are replying to, due to lack of relevant
quotes. See my sig. below for a cure.

This code is fatally flawed. It is storing data via uninitialized
pointers, and can do absolutely anything, including appearing to
work. It also uses gets, which is always a fatal error, because it
is uncontrollable. So even if you initialize the pointers behavior
will remain undefined.

For an example of code that can store and arbitrary number of
arbitrary strings in memory (barring memory exhaustion) see the
freverse demonstration in my ggets package. You can download it
at:

<http://cbfalconer.home.att.net/download/ggets.zip>

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: How include a large array? Edward A. Falk C Programming 1 04-04-2013 08:07 PM
501 PIX "deny any any" "allow any any" Any Anybody? Networking Student Cisco 4 11-16-2006 10:40 PM
How to generate k+1 length strings from a list of k length strings? Girish Sahani Python 17 06-09-2006 11:01 AM
How to store strings from a file into an array? Newbie Randy Lovelace C Programming 5 05-22-2005 05:03 AM
How to input strings of any lengths into arrays of type: char *array[SIZE] ? arkobose@gmail.com C Programming 7 05-15-2005 08:00 PM



Advertisments