ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
(Note: This problem comes straight from my course textbook. But, it is not for a grade, nor is it homework. I do the exercises to learn the material, but the professor doesn't assign them - he doesn't even mention them)
This is from the chapter on C-Strings:
6. Write a function that will accept ten lines of user-input and store the entered lines as ten individual C-strings. Us a pointer array in your function.
Here is what I have:
Code:
#include <iostream>
int main()
{
int i;
char *textl[10];
char temp[81];
// here is the function to read the lines in
for (i=0; i<10; i++){
std::cout<<"Enter a line of text: ";
std::cin.getline(temp, 81);
textl[i] = temp;
}
// this will display the lines
for (i=0; i<10; i++){
std::cout<<textl[i]<<std::endl;
}
return 0;
}
With the above, I get 10 lines of the last entered text. I assume that textl is just getting the address of temp, which stays the same, but the information stored there changes, and displays. So I thought I would cut out the middle man and just go straight to textl with the following:
Code:
#include <iostream>
int main()
{
int i;
char *textl[10];
// here is the function to read the lines in
for (i=0; i<10; i++){
std::cout<<"Enter a line of text: ";
std::cin.getline(textl[i], 81);
}
// this will display the lines
for (i=0; i<10; i++){
std::cout<<textl[i]<<std::endl;
}
return 0;
}
But with this, I get a segmentation fault after I enter the second line of text.
This is the point where I am stuck. Any help would be appreciated.
Forgive me for saying so, but you are wrong in what you just said,
Quote:
That is how the book says to declare it.
, but then the book also told you how to write it and you were prepared to change that, so perhaps you have to change the structure/s also and David has pointed you in the right direction. After all, you don't make a motorbike by taking two wheels off of a car, now do you? I think that David is giving you the direction so that you can have a bit of think about it for yourself. Otherwise what's the point. I'm sure that David has it sorted, but then he isn't in the seat trying to expand his learning in this area, is he? There is going to be a number of people out there taking your example and solving the problem for themselves,. You know that learning isn't to do with asking for answers it's asking for direction. Good luck.
PAix
Last edited by PAix; 11-13-2007 at 02:36 PM.
Reason: sorting my bad grammer
The problem tells me to use a pointer array. And the book says:
Quote:
The declaration of an array of character pointers is an extremely useful extension to single string pointer declarations. For example, the declaration
char *seasons[4];
creates an array of four elements, where each element is a pointer to a character. As individuals pointers, each pointer can be assigned to point to a string using string assignment statements. Thus the statements
set appropriate addresses into the respective pointers.
A First Book of C++: From Here to There - by Gary J. Bronson
pg. 481
I am sure that you guys know what exactly is wrong. And you're right, I don't want just an answer, I want mostly an understanding. But the clue given to me isn't jump-starting my brain. I just don't see anything wrong with my pointer array declaration, sorry.
I am sure that you guys know what exactly is wrong. And you're right, I don't want just an answer, I want mostly an understanding. But the clue given to me isn't jump-starting my brain. I just don't see anything wrong with my pointer array declaration, sorry.
Well, we do this for a living.
Quote:
Originally Posted by JMJ_coder
Here is what I have:
Code:
char *textl[10];
char temp[81];
What are the values of text1[0], text1[1], ..., text1[9]?
What is the value of temp?
Did you even know that temp could have a value?
This is C/C++, not BASIC, so you have to do some heavy lifting. Look up the functions malloc, calloc, and free in your textbook. They will probably have some examples of what you are looking for.
You will also want to look at strcpy and memcpy. There is an important difference between the two.
Last edited by David1357; 11-13-2007 at 05:48 PM.
Reason: Added mention of strcpy and memcpy
This exercise in pure C is far from trivial. You would help yourself by learning exactly what pointers are and how they work. For example if you dont understand what this does.
Code:
char array[30];
char **a;
char *p;
p = &array[0];
while ( ( c = getc(stdin) ) != '\n' )
{
*p++ = c;
}
*p = '\0';
p = array;
a[0] = p;
cout << a[0] << endl;
And why it would segfault after 30 chars, and even more importantly what you would have to do to make it handle as many chars as you input then you really need to sit down and understand this stuff, really try to understand what all those things ive written above do. Once you understand pointers and like David said malloc and calloc, you can then move on to using C++'s new and delete.
You said above that you 'assume', with a programming language like C/C++ you need to know. The best advice i can give you is, "learn the fundamentals"
NOW about your question.
Code:
When you declare *textl[10] you are declaring an array of pointers to type char.
When you declare char temp[81] you are declaring an array of chars that is
81 consecutive characters to which &temp[0] is the start of that array.
Code:
When you say textl[0] = temp , you are saying point the pointer at textl[0] to the start of the char array temp, infact, textl[0] = temp is just like saying
textl[0] = &temp[0].
Now when you DONT do that and you just say getline(textl[i], 81), you are saying, hey get 81 chars from the input stream and write them into the pointer textl[i].Now because your writing directly into a pointer, that at this stage is pointing nowhere or to some undefined place you get a segmentation fault.
If in your example you had allocated the memory in all of those pointers then you would have no problem, for example if you had put
Code:
for (int a = 0;a < 10 ;a++)
{
textl[a] = (char *)malloc(81);
}
just before you try to read all those strings in then it would work.
Do you understand?
The above code will initialize all the pointers to hold 81 chars.
So when you then go getline(textl[i],81), the pointer your getline() function is writing into actually has somewhere to write to.
You not understanding why your getting a segmentation fault is due, to not understanding how the language works.
For example being able to tell what a statement like: char *bleh = "this is a string"
actually does is very important. Not knowing what is really going on here allows you to assume things like getline(textl[i], 81) shouldnt fail, i mean if i can assign a sentence into a pointer when i declare it, i should be able to read a string into a an un initialized pointer right? wrong!
For the above example when you write char *bleh = "some stuff", what happens is c declares some memory say enough to hold the string, which in this case is 10 chars, which you could do by calling malloc, memory allocation, like malloc(11), next it will fill 10 of those chars up with the string "some stuff", it will then use that last char to null terminate the string, that is the char '\0'. It then will send back a pointer to the first character in that array and assign the symbol bleh to it.
Code:
So you have a pointer to some memory that would be mapped out like this -> s o m e s t u f f \0, the pointer is pointing to
the first char 's'. When you call say this pointer to be printed out to the screen with say cout << bleh << endl, it will print stuff out until it reaches the null at the end \0.
Now malloc as its name suggests allocates memory. so malloc(23) will allocate 23 chars of memory and send back a void pointer.
So char *p = (char *)malloc(23) will allocate 23 chars like ( char men[23] ) and return back a void pointer which you then cast to a char * pointer and assign it to the symbol p.
Now you can reference all those chars like p[0] p[1] etc and assign chars into them like p[0] = 's' p[1] = 'o'.You must learn all of this and more, C and C++ are fantastic languages, but they deserve your undivided attention. Do you see why the guys above said what they did, because they cannot spend all this time to explain to you how the C language works, which is the only way to properly answer your question. Instead they are pointing you in the right direction to learn all this stuff yourself.
I got the program working. Here is the final code:
Code:
#include <iostream>
int main()
{
int i;
char *textl[10];
char *temp;
for (i=0; i<10; i++){
temp = new char [81];
std::cout<<"Enter a line of text: ";
std::cin.getline(temp, 81);
textl[i] = temp;
}
for (i=0; i<10; i++){
std::cout<<textl[i]<<std::endl;
}
return 0;
}
The key was the new command. I had tried this before I even posted the first time, but I added a delete command at the end of the loop that was defeating the purpose. I got rid of the delete and all is well.
This is C/C++, not BASIC, so you have to do some heavy lifting. Look up the functions malloc, calloc, and free in your textbook. They will probably have some examples of what you are looking for.
You will also want to look at strcpy and memcpy. There is an important difference between the two.
My book doesn't even mention malloc, calloc, free or memcpy. I had to look them up on the internet to see what they were. The book does mention strcpy and I was thinking about it while I was creating the program.
I know it must be trying talking to a learning programmer like me, but I appreciate the help.
You said above that you 'assume', with a programming language like C/C++ you need to know. The best advice i can give you is, "learn the fundamentals"
I'm trying. I'm still working on my first programming class which teaches C++. That's the class the book is for (even though the professor doesn't really use it). The two MAJOR topics left to be learned in the semester are structures (which we began today) and classes. I agree, I want to learn the fundamentals, which is why I make it a point to do all the programming exercises in the book, even though the professor doesn't assign them (other than the first day, he hasn't mentioned the book).
Ah its a pleasure to help a beginning programmer, IF, they listen to what you are saying. I recommend looking at all the stuff i wrote above, if you can re-read it you will see things like
Quote:
Once you understand pointers and like David said malloc and calloc, you can then move on to using C++'s new and delete.
Here is an exercise for you, write me a post back, explaining WHY the 'new' works AND why this did NOT work
Code:
for (i=0; i<10; i++){
std::cout<<"Enter a line of text: ";
std::cin.getline(textl[i], 81);
}
what you really want to be able to do is something like this
functions.h
Code:
#ifndef FUNCTIONS_H
#define FUNCTIONS_H
char *getString();//function to get a string from stdin
char *resize(char *p, int size);//function to resize strings
#endif
function.c
Code:
#include "functions.h"
#include "stdlib.h"
#include "stdio.h"
#define STRSIZE 30
char *getString()
{
char *str = (char *)malloc(30);//start off with thirty, i mean, why not
char *start = str;
char c;
int size = STRSIZE;
int pos = 0;
while ((c = getc(stdin))!= '\n' ){
//test to see if we have enough room in our string
if ( !(pos < size) ){
str = resize(str, size);
start = str;
str += size;
}
*str++ = c;
}
*str = '\0';
return start;
}
char *resize(char *str, int size)
{
int i;
//create a new string thats STRSIZE bigger
char *newstring = (char *)malloc(STRSIZE+size);
//copy the data across
for( i = 0;i < size;i++){
newstring[i] = str[i];
}
free(str);
return newstring;
}
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.