Array of pointers to char...messed up!

Reply

Join Date: Oct 2009
Posts: 63
Reputation: neithan is an unknown quantity at this point 
Solved Threads: 2
neithan's Avatar
neithan neithan is offline Offline
Junior Poster in Training

Array of pointers to char...messed up!

 
0
  #1
28 Days Ago
I want to finaly learn what's up with pointers and arrays, so i made up this program:

#include <stdio.h>

int main()
{
    int cantidad_frases = 0;
    printf("Cuantas frases quieres escribir?: ");
    scanf("%d", &cantidad_frases);
    char *frases[cantidad_frases];
    for(unsigned i = 0; i < cantidad_frases; i++)
    {
        for(; *frases[i]; frases[i]++)
        {
            *frases[i] = getchar();
        }
    }
    printf("\nReproduciendo las frases:\n\n");
    for(unsigned i = 0; i < cantidad_frases; i++)
    {
        printf("Frase %d:", i + 1);
        for(; *frases[i]; frases[i]++)
        {
            printf("%c", *frases[i]);
        }
        printf("\n");
    }
    return 0;
}

I had no errors nor warnings at all. But program crashes after entering the cantidad_frases value and hitting enter. The problem is in the 11th line.

I really didn't know how to "refer" each letter of the words/string stored in frases[i].
I hope i made my question clear enough so you can help me. Any advise or (please) any specific place where they explain the whole thing about pointers and arrays is more than welcome!
Reply With Quote Quick reply to this message  
Join Date: Jan 2008
Posts: 344
Reputation: gerard4143 is on a distinguished road 
Solved Threads: 44
gerard4143's Avatar
gerard4143 gerard4143 is offline Offline
Posting Whiz
 
0
  #2
28 Days Ago
This line should probably be:

char *frases[cantidad_frases];

  1. char *frases = (char*)malloc(cantidad_frases);

So that you have allocated the memory...
Last edited by gerard4143; 28 Days Ago at 8:34 pm.
Reply With Quote Quick reply to this message  
Join Date: Sep 2009
Posts: 332
Reputation: dkalita will become famous soon enough dkalita will become famous soon enough 
Solved Threads: 46
dkalita's Avatar
dkalita dkalita is offline Offline
Posting Whiz
 
0
  #3
28 Days Ago
  1. for(unsigned i = 0; i < cantidad_frases; i++)
  2. {
  3. for(; *frases[i]; frases[i]++)
  4. {
  5. *frases[i] = getchar();
  6. }
  7. }
U have not assigned memory to frases[i].

Do
  1. #define MAX_STR 40 // whatever u want
  2. frases[i] = malloc(MAX_STR);
U are alos doing another mistake:
  1. for(; *frases[i]; frases[i]++)
here frases[i] is getting incremented. Hence the pointer advances and when later u want the inputed string u wont have it because the pointer has advanced to the end hence it contain nothing. U should do this with some temp pointer as
  1.  
  2. for(unsigned i = 0; i < cantidad_frases; i++)
  3. {
  4. frases[i] = malloc(MAX_STR);
  5. char *tmp = frases[i];
  6. for(; *tmp; tmp++)//AGAIN HERE U SHOULD MODIFY YOUR LOGIC BECAUSE frases[i] initially contains nothing. I am leaving it to you.
  7. {
  8. *tmp = getchar();
  9. }
  10. }
Last edited by dkalita; 28 Days Ago at 3:15 am.
Reply With Quote Quick reply to this message  
Join Date: May 2006
Posts: 3,114
Reputation: WaltP has much to be proud of WaltP has much to be proud of WaltP has much to be proud of WaltP has much to be proud of WaltP has much to be proud of WaltP has much to be proud of WaltP has much to be proud of WaltP has much to be proud of WaltP has much to be proud of 
Solved Threads: 281
Moderator
WaltP's Avatar
WaltP WaltP is offline Offline
Posting Sensei
 
0
  #4
28 Days Ago
And in C for(unsigned i = 0; i < cantidad_frases; i++) is illegal.
i must be defined before it is used, not in the for statement.
The 3 Laws of the Procrastination Society:
1) Never do today that which can be put off until tomorrow
2) Tomorrow never comes
Reply With Quote Quick reply to this message  
Join Date: Oct 2009
Posts: 63
Reputation: neithan is an unknown quantity at this point 
Solved Threads: 2
neithan's Avatar
neithan neithan is offline Offline
Junior Poster in Training
 
0
  #5
27 Days Ago
Originally Posted by gerard4143 View Post
This line should probably be:

char *frases[cantidad_frases];

  1. char *frases = (char*)malloc(cantidad_frases);

So that you have allocated the memory...
Originally Posted by dkalita View Post
  1.  
  2. for(unsigned i = 0; i < cantidad_frases; i++)
  3. {
  4. frases[i] = malloc(MAX_STR);
  5. char *tmp = frases[i];
  6. for(; *tmp; tmp++)//AGAIN HERE U SHOULD MODIFY YOUR LOGIC BECAUSE frases[i] initially contains nothing. I am leaving it to you.
  7. {
  8. *tmp = getchar();
  9. }
  10. }
char *tmp = frases[i]; <--- i'm confused here. Where does tmp point at?
Originally Posted by WaltP View Post
And in C for(unsigned i = 0; i < cantidad_frases; i++) is illegal.
i must be defined before it is used, not in the for statement.
I'm told in C99 is perfectly accepted?


OK so i see my fault was all about memory allocation, so im going to learn about that cause i know nothing.
However, if you had this *frases[].. let's say it cointains:
*frases[0] -> "tutorials"
*frases[1] -> "dani web"
*frases[2] -> "it discussion"

How would you refer to the w in web at frases[1]?

Thank you
Reply With Quote Quick reply to this message  
Join Date: Dec 2006
Posts: 2,029
Reputation: Aia has much to be proud of Aia has much to be proud of Aia has much to be proud of Aia has much to be proud of Aia has much to be proud of Aia has much to be proud of Aia has much to be proud of Aia has much to be proud of Aia has much to be proud of Aia has much to be proud of 
Solved Threads: 176
Aia's Avatar
Aia Aia is offline Offline
Postaholic
 
0
  #6
27 Days Ago
How would you refer to the w in web at frases[1]?
  1. frases[1][5];
or if you want to complicate it
  1. *(*(frases + 1)+ 5)
Last edited by Aia; 27 Days Ago at 7:48 pm.
Reply With Quote Quick reply to this message  
Join Date: Oct 2009
Posts: 63
Reputation: neithan is an unknown quantity at this point 
Solved Threads: 2
neithan's Avatar
neithan neithan is offline Offline
Junior Poster in Training
 
0
  #7
26 Days Ago
Originally Posted by Aia View Post
  1. frases[1][5];
or if you want to complicate it
  1. *(*(frases + 1)+ 5)
Awesome. The complicated version...heheh yes.
frases is pointing at 0, so +1 makes it look at the second phrase. And then the * dereference symbol, would return what? The first word in the first phrase? --> *( ? ) + 5 <---- ? should be a memory adress so it can be added with 5 and then dereference returning the "w" letter. But how come just doing *(frases + 1) returns not the value but a memory address?

Instead of mallocation before user's input, isn't the way to allocate at the same time user inputs so you reserve the exact memory needed? Like in run time.

Thank you for your time, i'm learning a lot. I'm gonna focus learning memory, malloc and pointers stuff more.
Reply With Quote Quick reply to this message  
Join Date: Oct 2009
Posts: 63
Reputation: neithan is an unknown quantity at this point 
Solved Threads: 2
neithan's Avatar
neithan neithan is offline Offline
Junior Poster in Training
 
0
  #8
25 Days Ago
I made it! It works perfectly thanks to your advices and further studying hehe. Any comments / corrections?

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. int main()
  5. {
  6. int cantidad_frases = 0;
  7. printf("Cuantas frases quieres escribir?: ");
  8. scanf("%d", &cantidad_frases);
  9. getchar();
  10. char *frases[cantidad_frases];
  11. for(unsigned i = 0; i < cantidad_frases; i++)
  12. {
  13. frases[i] = (char *) malloc(sizeof(char[20]));
  14. char *tmp = frases[i];
  15. printf("Escribe la frase %d: ", i+1);
  16. while((*tmp = getchar()))
  17. {
  18. if(*tmp == 10)
  19. {
  20. *tmp = '\0';
  21. break;
  22. }
  23. tmp++;
  24. }
  25. }
  26. for (unsigned i = 0; i < cantidad_frases; i++)
  27. {
  28. puts(frases[i]);
  29. }
  30.  
  31. return 0;
  32. }

I was turning mad when i saw phrase one was skipped. I realized there was a remanent \n in the buffer (by the line feed in the cantidad_frases selection). So i added the getchar() after the scanf to clean that up. Is there any elegant way to do it? EDIT: other than using another input function.
Last edited by neithan; 25 Days Ago at 8:46 pm.
Reply With Quote Quick reply to this message  
Join Date: Dec 2006
Posts: 2,029
Reputation: Aia has much to be proud of Aia has much to be proud of Aia has much to be proud of Aia has much to be proud of Aia has much to be proud of Aia has much to be proud of Aia has much to be proud of Aia has much to be proud of Aia has much to be proud of Aia has much to be proud of 
Solved Threads: 176
Aia's Avatar
Aia Aia is offline Offline
Postaholic
 
1
  #9
24 Days Ago
Any comments / corrections?
In the C89 standard, an array must be set with a constant. Which would not allowed what you just did.
  1. int cantidad_frases = 0;
  2. printf("Cuantas frases quieres escribir?: ");
  3. scanf("%d", &cantidad_frases);
  4. getchar();
  5. char *frases[cantidad_frases]; /* This is not allowed in C89 */
Furthermore, there can not be mixing of variable declarations and code. All variable must be declared first in the block. Making char *frases[cantid_frases]; incorrect as well.
If you want dynamically allocated multidimensional arrays you may take a look at pointer to pointer. Example

C89 doesn't accept declaration of variable in the for loop construct.
for(unsigned i = 0; i < cantidad_frases; i++)
Variable i must be declared outside the ().

When you ask for user input, the control of the program is handled to the user. They can enter an integer (in which case an enter key has been added to the stream), they can enter a float, a char or any combination and length of those. Moreover they might just press enter or be generous with blank sequence.
Can scanf() handle that kind of conditions? The answer is no. The elegant option then is to think how would you deal with the input and design your program to accommodate for those possibilities. There's not "silver-bullet function" that will do that for you.
Reply With Quote Quick reply to this message  
Join Date: Oct 2009
Posts: 63
Reputation: neithan is an unknown quantity at this point 
Solved Threads: 2
neithan's Avatar
neithan neithan is offline Offline
Junior Poster in Training
 
0
  #10
24 Days Ago
Originally Posted by Aia View Post
In the C89 standard, an array must be set with a constant. Which would not allowed what you just did.
Furthermore, there can not be mixing of variable declarations and code. All variable must be declared first in the block. Making char *frases[cantid_frases]; incorrect as well.
Ok but, i'm sorry if this sound ignorant which probably will, isn't C89 too old? I look it up and this C99 thing works with those issues, right? Why still thinking of C89? (remember i'm a beginner)


Originally Posted by Aia View Post
If you want dynamically allocated multidimensional arrays you may take a look at pointer to pointer. Example
I'm going to check that url and see what i can learn.

Originally Posted by Aia View Post
When you ask for user input, the control of the program is handled to the user. They can enter an integer (in which case an enter key has been added to the stream), they can enter a float, a char or any combination and length of those. Moreover they might just press enter or be generous with blank sequence.
Can scanf() handle that kind of conditions? The answer is no. The elegant option then is to think how would you deal with the input and design your program to accommodate for those possibilities. There's not "silver-bullet function" that will do that for you.
That is true...i'll see if i can improve that.

Thank you.
Reply With Quote Quick reply to this message  
Reply

Message:


Thread Tools Search this Thread



About Us | Contact Us | Advertise | DaniWeb | Acceptable Use Policy | RSS Feed

©2003 - 2009 DaniWeb® LLC