Read a string char by char from an associative pointer array












-1















Solved



I create a new char *ch malloc(strlen) and loop that string char by char. Then i copy it back using memcpy(ch, &stringpool[index], len) Of course, afterwards free(ch).





I hope the title of my question is correct.



I have a stringpool



char **string_pool;


that gets initiated in a function like



string_pool = malloc( sizeof(char *) * 1024);


i get strings from stdin and scanf them into the array



scanf("%[^n]s", &string_pool[index]);


so i can print it out using printf



printf("gets %sn", &string_pool[index]);


how can i




  • get the length of string_pool[index]

  • read string_pool[index] char by char in a loop


Thank you



Edit



Maybe i should explain it a bit more, its a virtual machine with a virtual instruction set and a program like



push 1
read
gets


should :




  • push 1 on the stack -> let x be 1

  • read stdin as string into string_pool[x]

  • push all characters onto the stack


the functions looks like



    case GETS: {
int index = popv(); // index is already on top of the stack
int strl = strlen(&string_pool[index]);

printf("gets %s with a length of %dn", &string_pool[index], strl);
// pseudo code
// push each char as integer on the stack
foreach(char in string_pool[index]) push((int)char);

break;
}

case READ: {
int index = popv();
scanf("%[^n]s", &string_pool[index]);
break;
}

case WRITE: {
int index = popv();
printf("%s", &string_pool[index]);
break;
}


My problem is in the GETS case. I want to push every char as int onto the stack.










share|improve this question

























  • What's wrong with using strlen()?

    – DYZ
    Jan 19 at 21:15











  • when i use strlen(&string_pool[i]) i get a compiler error expected 'const char *' but argument is of type 'char **'

    – StrangerThings
    Jan 19 at 21:21






  • 1





    scanf("%[^n]s", string_pool[index]); will cause undefined behavior, since you have not allocated any space for string_pool[index].

    – FredK
    Jan 19 at 21:30








  • 2





    Please show an MCVE (Minimal, Complete, and Verifiable example). It is not clear what you're up to with your edit.

    – Jonathan Leffler
    Jan 19 at 22:12








  • 1





    What is your actual question? What is the problem you are having? The title is an instruction, not a question.

    – Mad Physicist
    Jan 19 at 22:30
















-1















Solved



I create a new char *ch malloc(strlen) and loop that string char by char. Then i copy it back using memcpy(ch, &stringpool[index], len) Of course, afterwards free(ch).





I hope the title of my question is correct.



I have a stringpool



char **string_pool;


that gets initiated in a function like



string_pool = malloc( sizeof(char *) * 1024);


i get strings from stdin and scanf them into the array



scanf("%[^n]s", &string_pool[index]);


so i can print it out using printf



printf("gets %sn", &string_pool[index]);


how can i




  • get the length of string_pool[index]

  • read string_pool[index] char by char in a loop


Thank you



Edit



Maybe i should explain it a bit more, its a virtual machine with a virtual instruction set and a program like



push 1
read
gets


should :




  • push 1 on the stack -> let x be 1

  • read stdin as string into string_pool[x]

  • push all characters onto the stack


the functions looks like



    case GETS: {
int index = popv(); // index is already on top of the stack
int strl = strlen(&string_pool[index]);

printf("gets %s with a length of %dn", &string_pool[index], strl);
// pseudo code
// push each char as integer on the stack
foreach(char in string_pool[index]) push((int)char);

break;
}

case READ: {
int index = popv();
scanf("%[^n]s", &string_pool[index]);
break;
}

case WRITE: {
int index = popv();
printf("%s", &string_pool[index]);
break;
}


My problem is in the GETS case. I want to push every char as int onto the stack.










share|improve this question

























  • What's wrong with using strlen()?

    – DYZ
    Jan 19 at 21:15











  • when i use strlen(&string_pool[i]) i get a compiler error expected 'const char *' but argument is of type 'char **'

    – StrangerThings
    Jan 19 at 21:21






  • 1





    scanf("%[^n]s", string_pool[index]); will cause undefined behavior, since you have not allocated any space for string_pool[index].

    – FredK
    Jan 19 at 21:30








  • 2





    Please show an MCVE (Minimal, Complete, and Verifiable example). It is not clear what you're up to with your edit.

    – Jonathan Leffler
    Jan 19 at 22:12








  • 1





    What is your actual question? What is the problem you are having? The title is an instruction, not a question.

    – Mad Physicist
    Jan 19 at 22:30














-1












-1








-1








Solved



I create a new char *ch malloc(strlen) and loop that string char by char. Then i copy it back using memcpy(ch, &stringpool[index], len) Of course, afterwards free(ch).





I hope the title of my question is correct.



I have a stringpool



char **string_pool;


that gets initiated in a function like



string_pool = malloc( sizeof(char *) * 1024);


i get strings from stdin and scanf them into the array



scanf("%[^n]s", &string_pool[index]);


so i can print it out using printf



printf("gets %sn", &string_pool[index]);


how can i




  • get the length of string_pool[index]

  • read string_pool[index] char by char in a loop


Thank you



Edit



Maybe i should explain it a bit more, its a virtual machine with a virtual instruction set and a program like



push 1
read
gets


should :




  • push 1 on the stack -> let x be 1

  • read stdin as string into string_pool[x]

  • push all characters onto the stack


the functions looks like



    case GETS: {
int index = popv(); // index is already on top of the stack
int strl = strlen(&string_pool[index]);

printf("gets %s with a length of %dn", &string_pool[index], strl);
// pseudo code
// push each char as integer on the stack
foreach(char in string_pool[index]) push((int)char);

break;
}

case READ: {
int index = popv();
scanf("%[^n]s", &string_pool[index]);
break;
}

case WRITE: {
int index = popv();
printf("%s", &string_pool[index]);
break;
}


My problem is in the GETS case. I want to push every char as int onto the stack.










share|improve this question
















Solved



I create a new char *ch malloc(strlen) and loop that string char by char. Then i copy it back using memcpy(ch, &stringpool[index], len) Of course, afterwards free(ch).





I hope the title of my question is correct.



I have a stringpool



char **string_pool;


that gets initiated in a function like



string_pool = malloc( sizeof(char *) * 1024);


i get strings from stdin and scanf them into the array



scanf("%[^n]s", &string_pool[index]);


so i can print it out using printf



printf("gets %sn", &string_pool[index]);


how can i




  • get the length of string_pool[index]

  • read string_pool[index] char by char in a loop


Thank you



Edit



Maybe i should explain it a bit more, its a virtual machine with a virtual instruction set and a program like



push 1
read
gets


should :




  • push 1 on the stack -> let x be 1

  • read stdin as string into string_pool[x]

  • push all characters onto the stack


the functions looks like



    case GETS: {
int index = popv(); // index is already on top of the stack
int strl = strlen(&string_pool[index]);

printf("gets %s with a length of %dn", &string_pool[index], strl);
// pseudo code
// push each char as integer on the stack
foreach(char in string_pool[index]) push((int)char);

break;
}

case READ: {
int index = popv();
scanf("%[^n]s", &string_pool[index]);
break;
}

case WRITE: {
int index = popv();
printf("%s", &string_pool[index]);
break;
}


My problem is in the GETS case. I want to push every char as int onto the stack.







c arrays string pointers






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Jan 20 at 17:10







StrangerThings

















asked Jan 19 at 21:12









StrangerThingsStrangerThings

156




156













  • What's wrong with using strlen()?

    – DYZ
    Jan 19 at 21:15











  • when i use strlen(&string_pool[i]) i get a compiler error expected 'const char *' but argument is of type 'char **'

    – StrangerThings
    Jan 19 at 21:21






  • 1





    scanf("%[^n]s", string_pool[index]); will cause undefined behavior, since you have not allocated any space for string_pool[index].

    – FredK
    Jan 19 at 21:30








  • 2





    Please show an MCVE (Minimal, Complete, and Verifiable example). It is not clear what you're up to with your edit.

    – Jonathan Leffler
    Jan 19 at 22:12








  • 1





    What is your actual question? What is the problem you are having? The title is an instruction, not a question.

    – Mad Physicist
    Jan 19 at 22:30



















  • What's wrong with using strlen()?

    – DYZ
    Jan 19 at 21:15











  • when i use strlen(&string_pool[i]) i get a compiler error expected 'const char *' but argument is of type 'char **'

    – StrangerThings
    Jan 19 at 21:21






  • 1





    scanf("%[^n]s", string_pool[index]); will cause undefined behavior, since you have not allocated any space for string_pool[index].

    – FredK
    Jan 19 at 21:30








  • 2





    Please show an MCVE (Minimal, Complete, and Verifiable example). It is not clear what you're up to with your edit.

    – Jonathan Leffler
    Jan 19 at 22:12








  • 1





    What is your actual question? What is the problem you are having? The title is an instruction, not a question.

    – Mad Physicist
    Jan 19 at 22:30

















What's wrong with using strlen()?

– DYZ
Jan 19 at 21:15





What's wrong with using strlen()?

– DYZ
Jan 19 at 21:15













when i use strlen(&string_pool[i]) i get a compiler error expected 'const char *' but argument is of type 'char **'

– StrangerThings
Jan 19 at 21:21





when i use strlen(&string_pool[i]) i get a compiler error expected 'const char *' but argument is of type 'char **'

– StrangerThings
Jan 19 at 21:21




1




1





scanf("%[^n]s", string_pool[index]); will cause undefined behavior, since you have not allocated any space for string_pool[index].

– FredK
Jan 19 at 21:30







scanf("%[^n]s", string_pool[index]); will cause undefined behavior, since you have not allocated any space for string_pool[index].

– FredK
Jan 19 at 21:30






2




2





Please show an MCVE (Minimal, Complete, and Verifiable example). It is not clear what you're up to with your edit.

– Jonathan Leffler
Jan 19 at 22:12







Please show an MCVE (Minimal, Complete, and Verifiable example). It is not clear what you're up to with your edit.

– Jonathan Leffler
Jan 19 at 22:12






1




1





What is your actual question? What is the problem you are having? The title is an instruction, not a question.

– Mad Physicist
Jan 19 at 22:30





What is your actual question? What is the problem you are having? The title is an instruction, not a question.

– Mad Physicist
Jan 19 at 22:30












3 Answers
3






active

oldest

votes


















1















char **string_pool;
string_pool = malloc( sizeof(char *) * 1024);



Allocates 1024 pointers-to-char. (string_pool is a pointer-to-pointer-to-char) Each of the pointers are uninitialized and point to no valid storage that can be used. Before you can use each pointer, you must make them point to valid memory by allocating memory and assigning the starting address to each pointer (so that each pointer "points" to valid memory).



To allow proper sizing and allocation for each string your read, you will either use fgets with a fixed buffer sufficient to store the longest input you expect, or you can use POSIX getline which will allocate storage for input as required. Using fgets you would do something similar to:



#define MAXCHR 2048
...

char buffer[MAXCHR];

fputs ("enter string: ", stdout);
if (fgets (buffer, MAXCHR, stdin) == NULL) {
fputs ("(user canceled input.)n", stderr);
return 1;
}

size_t len = strlen (buffer); /* get the length of input (with 'n') */
if (len && buffer[len - 1] == 'n') /* trim the 'n' from end */
buffer[--len] = 0; /* by overwriting with nul-character */


string_pool[index] = malloc (len + 1); /* allocate storage for buffer */
if (string_pool[index] == NULL) { /* validate allocation */
perror ("maklloc-string_pool[index]"); /* handle error */
return 1; /* or break read loop; */
}
/* copy buffer to string_pool[index], advance index */
memcpy (string_pool[index++], buffer, len + 1);


You would generally do this within your read loop only allowing input while index < 1024 to insure you did not attempt to allocate storage for one pointer too many.



Look things over and let me know if you have questions.






share|improve this answer
























  • I am looking for the other direction - to GET a string already stored

    – StrangerThings
    Jan 19 at 21:47











  • No problems, then you just assign the address for the already stored string to your string_pool[index] pointer. Since you have 1024 pointers, they can be made to point to any valid string you already have by simple assignment. (but note, following assignment, if what the pointer points to goes out of scope, then attempting to reference the string through the pointer will result in Undefined Behavior)

    – David C. Rankin
    Jan 19 at 22:13













  • please read my edited question again. look at the case: GETS statement in the last codeblock

    – StrangerThings
    Jan 19 at 22:19













  • OK, I still think you are confusing pointers and stack storage, etc.. For instance, scanf("%[^n]s", &string_pool[index]); is invalid. string_pool[index] is type char* (which corresponds to the pointer type %[...] requires). When you attempt to use &string_pool[index]), that is type char** and invokes undefined behavior. When you are reading with scanf (what I replaced with fgets above), you must have storage within which to store what is read. Attempting to mix assembly semantics reserving and pushing to the stack obscures the fact all strings will have the same address.

    – David C. Rankin
    Jan 19 at 23:57













  • I also think you are right :P i solved it by creating a buffer of size(strlen) and copy it with memcpy, you point me the direction +1, sorry

    – StrangerThings
    Jan 20 at 0:04





















0














You must allocate space for each string.
So, for example,



string_pool[0] = malloc( 100 );


will then allow you to read a string that is up to 99 characters long into string_pool[0] (the extra space is needed for the terminating null).






share|improve this answer
























  • I have to do this everytime i insert a new array? so if there are already 3 arrays, i have to do string_pool[3] = mallog(strlen)

    – StrangerThings
    Jan 19 at 21:40













  • Yes, you have to allocate space for each string in the array. Your original malloc only allocated space for the pointers, which remain uninitialized until you create space for each one of them.

    – FredK
    Jan 19 at 21:42











  • i dont understand how this belongs to my question. I have no problem storing the strings, my problem is to read them

    – StrangerThings
    Jan 19 at 21:49





















-1














To get string length:



int len = strlen(string_pool[index]);


This is because string_pool[x] is a pointer. &string_pool[x] gives address of the char*.



To read string_pool[index] char by char in a loop:



char *ptr = string_pool[index];
while(*ptr){
//use *ptr
ptr++;
}


This reads the string given by string_pool[index] till the end.



Note: To read a string using scanf, your code should be



scanf("%[^n]s", string_pool[index]);


EDIT: Hadn't noticed the allocation statement.



You need to assign memory individually for each string.
The code would be:



string_pool = malloc( sizeof(char *) * NO_STRS);
for(int i=0;i<NO_STRS; i++)
string_pool[i] = malloc(sizeof(char) * STR_LEN);





share|improve this answer


























  • But first you must allocate some space for string_pool[index]

    – FredK
    Jan 19 at 21:33











  • Thats what i try to archieve but it doesnt work. I have to use &string_pool[index] then strlen works. The loop doesnt work at all.

    – StrangerThings
    Jan 19 at 21:33











  • No, it doesn't work. It is undefined behavior, which can seem to work, but you are overwriting core.

    – FredK
    Jan 19 at 21:35











  • I also thought so but its just not working. I have to use the pointer to get it working. maybe there is my problem. I declare char **stringpool in the global scope, does that matter?.

    – StrangerThings
    Jan 19 at 21:36











  • @Susmit Agrawal *string_pool[i] is of type char, not char*.

    – FredK
    Jan 19 at 21:46













Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54271430%2fread-a-string-char-by-char-from-an-associative-pointer-array%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























3 Answers
3






active

oldest

votes








3 Answers
3






active

oldest

votes









active

oldest

votes






active

oldest

votes









1















char **string_pool;
string_pool = malloc( sizeof(char *) * 1024);



Allocates 1024 pointers-to-char. (string_pool is a pointer-to-pointer-to-char) Each of the pointers are uninitialized and point to no valid storage that can be used. Before you can use each pointer, you must make them point to valid memory by allocating memory and assigning the starting address to each pointer (so that each pointer "points" to valid memory).



To allow proper sizing and allocation for each string your read, you will either use fgets with a fixed buffer sufficient to store the longest input you expect, or you can use POSIX getline which will allocate storage for input as required. Using fgets you would do something similar to:



#define MAXCHR 2048
...

char buffer[MAXCHR];

fputs ("enter string: ", stdout);
if (fgets (buffer, MAXCHR, stdin) == NULL) {
fputs ("(user canceled input.)n", stderr);
return 1;
}

size_t len = strlen (buffer); /* get the length of input (with 'n') */
if (len && buffer[len - 1] == 'n') /* trim the 'n' from end */
buffer[--len] = 0; /* by overwriting with nul-character */


string_pool[index] = malloc (len + 1); /* allocate storage for buffer */
if (string_pool[index] == NULL) { /* validate allocation */
perror ("maklloc-string_pool[index]"); /* handle error */
return 1; /* or break read loop; */
}
/* copy buffer to string_pool[index], advance index */
memcpy (string_pool[index++], buffer, len + 1);


You would generally do this within your read loop only allowing input while index < 1024 to insure you did not attempt to allocate storage for one pointer too many.



Look things over and let me know if you have questions.






share|improve this answer
























  • I am looking for the other direction - to GET a string already stored

    – StrangerThings
    Jan 19 at 21:47











  • No problems, then you just assign the address for the already stored string to your string_pool[index] pointer. Since you have 1024 pointers, they can be made to point to any valid string you already have by simple assignment. (but note, following assignment, if what the pointer points to goes out of scope, then attempting to reference the string through the pointer will result in Undefined Behavior)

    – David C. Rankin
    Jan 19 at 22:13













  • please read my edited question again. look at the case: GETS statement in the last codeblock

    – StrangerThings
    Jan 19 at 22:19













  • OK, I still think you are confusing pointers and stack storage, etc.. For instance, scanf("%[^n]s", &string_pool[index]); is invalid. string_pool[index] is type char* (which corresponds to the pointer type %[...] requires). When you attempt to use &string_pool[index]), that is type char** and invokes undefined behavior. When you are reading with scanf (what I replaced with fgets above), you must have storage within which to store what is read. Attempting to mix assembly semantics reserving and pushing to the stack obscures the fact all strings will have the same address.

    – David C. Rankin
    Jan 19 at 23:57













  • I also think you are right :P i solved it by creating a buffer of size(strlen) and copy it with memcpy, you point me the direction +1, sorry

    – StrangerThings
    Jan 20 at 0:04


















1















char **string_pool;
string_pool = malloc( sizeof(char *) * 1024);



Allocates 1024 pointers-to-char. (string_pool is a pointer-to-pointer-to-char) Each of the pointers are uninitialized and point to no valid storage that can be used. Before you can use each pointer, you must make them point to valid memory by allocating memory and assigning the starting address to each pointer (so that each pointer "points" to valid memory).



To allow proper sizing and allocation for each string your read, you will either use fgets with a fixed buffer sufficient to store the longest input you expect, or you can use POSIX getline which will allocate storage for input as required. Using fgets you would do something similar to:



#define MAXCHR 2048
...

char buffer[MAXCHR];

fputs ("enter string: ", stdout);
if (fgets (buffer, MAXCHR, stdin) == NULL) {
fputs ("(user canceled input.)n", stderr);
return 1;
}

size_t len = strlen (buffer); /* get the length of input (with 'n') */
if (len && buffer[len - 1] == 'n') /* trim the 'n' from end */
buffer[--len] = 0; /* by overwriting with nul-character */


string_pool[index] = malloc (len + 1); /* allocate storage for buffer */
if (string_pool[index] == NULL) { /* validate allocation */
perror ("maklloc-string_pool[index]"); /* handle error */
return 1; /* or break read loop; */
}
/* copy buffer to string_pool[index], advance index */
memcpy (string_pool[index++], buffer, len + 1);


You would generally do this within your read loop only allowing input while index < 1024 to insure you did not attempt to allocate storage for one pointer too many.



Look things over and let me know if you have questions.






share|improve this answer
























  • I am looking for the other direction - to GET a string already stored

    – StrangerThings
    Jan 19 at 21:47











  • No problems, then you just assign the address for the already stored string to your string_pool[index] pointer. Since you have 1024 pointers, they can be made to point to any valid string you already have by simple assignment. (but note, following assignment, if what the pointer points to goes out of scope, then attempting to reference the string through the pointer will result in Undefined Behavior)

    – David C. Rankin
    Jan 19 at 22:13













  • please read my edited question again. look at the case: GETS statement in the last codeblock

    – StrangerThings
    Jan 19 at 22:19













  • OK, I still think you are confusing pointers and stack storage, etc.. For instance, scanf("%[^n]s", &string_pool[index]); is invalid. string_pool[index] is type char* (which corresponds to the pointer type %[...] requires). When you attempt to use &string_pool[index]), that is type char** and invokes undefined behavior. When you are reading with scanf (what I replaced with fgets above), you must have storage within which to store what is read. Attempting to mix assembly semantics reserving and pushing to the stack obscures the fact all strings will have the same address.

    – David C. Rankin
    Jan 19 at 23:57













  • I also think you are right :P i solved it by creating a buffer of size(strlen) and copy it with memcpy, you point me the direction +1, sorry

    – StrangerThings
    Jan 20 at 0:04
















1












1








1








char **string_pool;
string_pool = malloc( sizeof(char *) * 1024);



Allocates 1024 pointers-to-char. (string_pool is a pointer-to-pointer-to-char) Each of the pointers are uninitialized and point to no valid storage that can be used. Before you can use each pointer, you must make them point to valid memory by allocating memory and assigning the starting address to each pointer (so that each pointer "points" to valid memory).



To allow proper sizing and allocation for each string your read, you will either use fgets with a fixed buffer sufficient to store the longest input you expect, or you can use POSIX getline which will allocate storage for input as required. Using fgets you would do something similar to:



#define MAXCHR 2048
...

char buffer[MAXCHR];

fputs ("enter string: ", stdout);
if (fgets (buffer, MAXCHR, stdin) == NULL) {
fputs ("(user canceled input.)n", stderr);
return 1;
}

size_t len = strlen (buffer); /* get the length of input (with 'n') */
if (len && buffer[len - 1] == 'n') /* trim the 'n' from end */
buffer[--len] = 0; /* by overwriting with nul-character */


string_pool[index] = malloc (len + 1); /* allocate storage for buffer */
if (string_pool[index] == NULL) { /* validate allocation */
perror ("maklloc-string_pool[index]"); /* handle error */
return 1; /* or break read loop; */
}
/* copy buffer to string_pool[index], advance index */
memcpy (string_pool[index++], buffer, len + 1);


You would generally do this within your read loop only allowing input while index < 1024 to insure you did not attempt to allocate storage for one pointer too many.



Look things over and let me know if you have questions.






share|improve this answer














char **string_pool;
string_pool = malloc( sizeof(char *) * 1024);



Allocates 1024 pointers-to-char. (string_pool is a pointer-to-pointer-to-char) Each of the pointers are uninitialized and point to no valid storage that can be used. Before you can use each pointer, you must make them point to valid memory by allocating memory and assigning the starting address to each pointer (so that each pointer "points" to valid memory).



To allow proper sizing and allocation for each string your read, you will either use fgets with a fixed buffer sufficient to store the longest input you expect, or you can use POSIX getline which will allocate storage for input as required. Using fgets you would do something similar to:



#define MAXCHR 2048
...

char buffer[MAXCHR];

fputs ("enter string: ", stdout);
if (fgets (buffer, MAXCHR, stdin) == NULL) {
fputs ("(user canceled input.)n", stderr);
return 1;
}

size_t len = strlen (buffer); /* get the length of input (with 'n') */
if (len && buffer[len - 1] == 'n') /* trim the 'n' from end */
buffer[--len] = 0; /* by overwriting with nul-character */


string_pool[index] = malloc (len + 1); /* allocate storage for buffer */
if (string_pool[index] == NULL) { /* validate allocation */
perror ("maklloc-string_pool[index]"); /* handle error */
return 1; /* or break read loop; */
}
/* copy buffer to string_pool[index], advance index */
memcpy (string_pool[index++], buffer, len + 1);


You would generally do this within your read loop only allowing input while index < 1024 to insure you did not attempt to allocate storage for one pointer too many.



Look things over and let me know if you have questions.







share|improve this answer












share|improve this answer



share|improve this answer










answered Jan 19 at 21:41









David C. RankinDavid C. Rankin

41.6k32748




41.6k32748













  • I am looking for the other direction - to GET a string already stored

    – StrangerThings
    Jan 19 at 21:47











  • No problems, then you just assign the address for the already stored string to your string_pool[index] pointer. Since you have 1024 pointers, they can be made to point to any valid string you already have by simple assignment. (but note, following assignment, if what the pointer points to goes out of scope, then attempting to reference the string through the pointer will result in Undefined Behavior)

    – David C. Rankin
    Jan 19 at 22:13













  • please read my edited question again. look at the case: GETS statement in the last codeblock

    – StrangerThings
    Jan 19 at 22:19













  • OK, I still think you are confusing pointers and stack storage, etc.. For instance, scanf("%[^n]s", &string_pool[index]); is invalid. string_pool[index] is type char* (which corresponds to the pointer type %[...] requires). When you attempt to use &string_pool[index]), that is type char** and invokes undefined behavior. When you are reading with scanf (what I replaced with fgets above), you must have storage within which to store what is read. Attempting to mix assembly semantics reserving and pushing to the stack obscures the fact all strings will have the same address.

    – David C. Rankin
    Jan 19 at 23:57













  • I also think you are right :P i solved it by creating a buffer of size(strlen) and copy it with memcpy, you point me the direction +1, sorry

    – StrangerThings
    Jan 20 at 0:04





















  • I am looking for the other direction - to GET a string already stored

    – StrangerThings
    Jan 19 at 21:47











  • No problems, then you just assign the address for the already stored string to your string_pool[index] pointer. Since you have 1024 pointers, they can be made to point to any valid string you already have by simple assignment. (but note, following assignment, if what the pointer points to goes out of scope, then attempting to reference the string through the pointer will result in Undefined Behavior)

    – David C. Rankin
    Jan 19 at 22:13













  • please read my edited question again. look at the case: GETS statement in the last codeblock

    – StrangerThings
    Jan 19 at 22:19













  • OK, I still think you are confusing pointers and stack storage, etc.. For instance, scanf("%[^n]s", &string_pool[index]); is invalid. string_pool[index] is type char* (which corresponds to the pointer type %[...] requires). When you attempt to use &string_pool[index]), that is type char** and invokes undefined behavior. When you are reading with scanf (what I replaced with fgets above), you must have storage within which to store what is read. Attempting to mix assembly semantics reserving and pushing to the stack obscures the fact all strings will have the same address.

    – David C. Rankin
    Jan 19 at 23:57













  • I also think you are right :P i solved it by creating a buffer of size(strlen) and copy it with memcpy, you point me the direction +1, sorry

    – StrangerThings
    Jan 20 at 0:04



















I am looking for the other direction - to GET a string already stored

– StrangerThings
Jan 19 at 21:47





I am looking for the other direction - to GET a string already stored

– StrangerThings
Jan 19 at 21:47













No problems, then you just assign the address for the already stored string to your string_pool[index] pointer. Since you have 1024 pointers, they can be made to point to any valid string you already have by simple assignment. (but note, following assignment, if what the pointer points to goes out of scope, then attempting to reference the string through the pointer will result in Undefined Behavior)

– David C. Rankin
Jan 19 at 22:13







No problems, then you just assign the address for the already stored string to your string_pool[index] pointer. Since you have 1024 pointers, they can be made to point to any valid string you already have by simple assignment. (but note, following assignment, if what the pointer points to goes out of scope, then attempting to reference the string through the pointer will result in Undefined Behavior)

– David C. Rankin
Jan 19 at 22:13















please read my edited question again. look at the case: GETS statement in the last codeblock

– StrangerThings
Jan 19 at 22:19







please read my edited question again. look at the case: GETS statement in the last codeblock

– StrangerThings
Jan 19 at 22:19















OK, I still think you are confusing pointers and stack storage, etc.. For instance, scanf("%[^n]s", &string_pool[index]); is invalid. string_pool[index] is type char* (which corresponds to the pointer type %[...] requires). When you attempt to use &string_pool[index]), that is type char** and invokes undefined behavior. When you are reading with scanf (what I replaced with fgets above), you must have storage within which to store what is read. Attempting to mix assembly semantics reserving and pushing to the stack obscures the fact all strings will have the same address.

– David C. Rankin
Jan 19 at 23:57







OK, I still think you are confusing pointers and stack storage, etc.. For instance, scanf("%[^n]s", &string_pool[index]); is invalid. string_pool[index] is type char* (which corresponds to the pointer type %[...] requires). When you attempt to use &string_pool[index]), that is type char** and invokes undefined behavior. When you are reading with scanf (what I replaced with fgets above), you must have storage within which to store what is read. Attempting to mix assembly semantics reserving and pushing to the stack obscures the fact all strings will have the same address.

– David C. Rankin
Jan 19 at 23:57















I also think you are right :P i solved it by creating a buffer of size(strlen) and copy it with memcpy, you point me the direction +1, sorry

– StrangerThings
Jan 20 at 0:04







I also think you are right :P i solved it by creating a buffer of size(strlen) and copy it with memcpy, you point me the direction +1, sorry

– StrangerThings
Jan 20 at 0:04















0














You must allocate space for each string.
So, for example,



string_pool[0] = malloc( 100 );


will then allow you to read a string that is up to 99 characters long into string_pool[0] (the extra space is needed for the terminating null).






share|improve this answer
























  • I have to do this everytime i insert a new array? so if there are already 3 arrays, i have to do string_pool[3] = mallog(strlen)

    – StrangerThings
    Jan 19 at 21:40













  • Yes, you have to allocate space for each string in the array. Your original malloc only allocated space for the pointers, which remain uninitialized until you create space for each one of them.

    – FredK
    Jan 19 at 21:42











  • i dont understand how this belongs to my question. I have no problem storing the strings, my problem is to read them

    – StrangerThings
    Jan 19 at 21:49


















0














You must allocate space for each string.
So, for example,



string_pool[0] = malloc( 100 );


will then allow you to read a string that is up to 99 characters long into string_pool[0] (the extra space is needed for the terminating null).






share|improve this answer
























  • I have to do this everytime i insert a new array? so if there are already 3 arrays, i have to do string_pool[3] = mallog(strlen)

    – StrangerThings
    Jan 19 at 21:40













  • Yes, you have to allocate space for each string in the array. Your original malloc only allocated space for the pointers, which remain uninitialized until you create space for each one of them.

    – FredK
    Jan 19 at 21:42











  • i dont understand how this belongs to my question. I have no problem storing the strings, my problem is to read them

    – StrangerThings
    Jan 19 at 21:49
















0












0








0







You must allocate space for each string.
So, for example,



string_pool[0] = malloc( 100 );


will then allow you to read a string that is up to 99 characters long into string_pool[0] (the extra space is needed for the terminating null).






share|improve this answer













You must allocate space for each string.
So, for example,



string_pool[0] = malloc( 100 );


will then allow you to read a string that is up to 99 characters long into string_pool[0] (the extra space is needed for the terminating null).







share|improve this answer












share|improve this answer



share|improve this answer










answered Jan 19 at 21:37









FredKFredK

3,139149




3,139149













  • I have to do this everytime i insert a new array? so if there are already 3 arrays, i have to do string_pool[3] = mallog(strlen)

    – StrangerThings
    Jan 19 at 21:40













  • Yes, you have to allocate space for each string in the array. Your original malloc only allocated space for the pointers, which remain uninitialized until you create space for each one of them.

    – FredK
    Jan 19 at 21:42











  • i dont understand how this belongs to my question. I have no problem storing the strings, my problem is to read them

    – StrangerThings
    Jan 19 at 21:49





















  • I have to do this everytime i insert a new array? so if there are already 3 arrays, i have to do string_pool[3] = mallog(strlen)

    – StrangerThings
    Jan 19 at 21:40













  • Yes, you have to allocate space for each string in the array. Your original malloc only allocated space for the pointers, which remain uninitialized until you create space for each one of them.

    – FredK
    Jan 19 at 21:42











  • i dont understand how this belongs to my question. I have no problem storing the strings, my problem is to read them

    – StrangerThings
    Jan 19 at 21:49



















I have to do this everytime i insert a new array? so if there are already 3 arrays, i have to do string_pool[3] = mallog(strlen)

– StrangerThings
Jan 19 at 21:40







I have to do this everytime i insert a new array? so if there are already 3 arrays, i have to do string_pool[3] = mallog(strlen)

– StrangerThings
Jan 19 at 21:40















Yes, you have to allocate space for each string in the array. Your original malloc only allocated space for the pointers, which remain uninitialized until you create space for each one of them.

– FredK
Jan 19 at 21:42





Yes, you have to allocate space for each string in the array. Your original malloc only allocated space for the pointers, which remain uninitialized until you create space for each one of them.

– FredK
Jan 19 at 21:42













i dont understand how this belongs to my question. I have no problem storing the strings, my problem is to read them

– StrangerThings
Jan 19 at 21:49







i dont understand how this belongs to my question. I have no problem storing the strings, my problem is to read them

– StrangerThings
Jan 19 at 21:49













-1














To get string length:



int len = strlen(string_pool[index]);


This is because string_pool[x] is a pointer. &string_pool[x] gives address of the char*.



To read string_pool[index] char by char in a loop:



char *ptr = string_pool[index];
while(*ptr){
//use *ptr
ptr++;
}


This reads the string given by string_pool[index] till the end.



Note: To read a string using scanf, your code should be



scanf("%[^n]s", string_pool[index]);


EDIT: Hadn't noticed the allocation statement.



You need to assign memory individually for each string.
The code would be:



string_pool = malloc( sizeof(char *) * NO_STRS);
for(int i=0;i<NO_STRS; i++)
string_pool[i] = malloc(sizeof(char) * STR_LEN);





share|improve this answer


























  • But first you must allocate some space for string_pool[index]

    – FredK
    Jan 19 at 21:33











  • Thats what i try to archieve but it doesnt work. I have to use &string_pool[index] then strlen works. The loop doesnt work at all.

    – StrangerThings
    Jan 19 at 21:33











  • No, it doesn't work. It is undefined behavior, which can seem to work, but you are overwriting core.

    – FredK
    Jan 19 at 21:35











  • I also thought so but its just not working. I have to use the pointer to get it working. maybe there is my problem. I declare char **stringpool in the global scope, does that matter?.

    – StrangerThings
    Jan 19 at 21:36











  • @Susmit Agrawal *string_pool[i] is of type char, not char*.

    – FredK
    Jan 19 at 21:46


















-1














To get string length:



int len = strlen(string_pool[index]);


This is because string_pool[x] is a pointer. &string_pool[x] gives address of the char*.



To read string_pool[index] char by char in a loop:



char *ptr = string_pool[index];
while(*ptr){
//use *ptr
ptr++;
}


This reads the string given by string_pool[index] till the end.



Note: To read a string using scanf, your code should be



scanf("%[^n]s", string_pool[index]);


EDIT: Hadn't noticed the allocation statement.



You need to assign memory individually for each string.
The code would be:



string_pool = malloc( sizeof(char *) * NO_STRS);
for(int i=0;i<NO_STRS; i++)
string_pool[i] = malloc(sizeof(char) * STR_LEN);





share|improve this answer


























  • But first you must allocate some space for string_pool[index]

    – FredK
    Jan 19 at 21:33











  • Thats what i try to archieve but it doesnt work. I have to use &string_pool[index] then strlen works. The loop doesnt work at all.

    – StrangerThings
    Jan 19 at 21:33











  • No, it doesn't work. It is undefined behavior, which can seem to work, but you are overwriting core.

    – FredK
    Jan 19 at 21:35











  • I also thought so but its just not working. I have to use the pointer to get it working. maybe there is my problem. I declare char **stringpool in the global scope, does that matter?.

    – StrangerThings
    Jan 19 at 21:36











  • @Susmit Agrawal *string_pool[i] is of type char, not char*.

    – FredK
    Jan 19 at 21:46
















-1












-1








-1







To get string length:



int len = strlen(string_pool[index]);


This is because string_pool[x] is a pointer. &string_pool[x] gives address of the char*.



To read string_pool[index] char by char in a loop:



char *ptr = string_pool[index];
while(*ptr){
//use *ptr
ptr++;
}


This reads the string given by string_pool[index] till the end.



Note: To read a string using scanf, your code should be



scanf("%[^n]s", string_pool[index]);


EDIT: Hadn't noticed the allocation statement.



You need to assign memory individually for each string.
The code would be:



string_pool = malloc( sizeof(char *) * NO_STRS);
for(int i=0;i<NO_STRS; i++)
string_pool[i] = malloc(sizeof(char) * STR_LEN);





share|improve this answer















To get string length:



int len = strlen(string_pool[index]);


This is because string_pool[x] is a pointer. &string_pool[x] gives address of the char*.



To read string_pool[index] char by char in a loop:



char *ptr = string_pool[index];
while(*ptr){
//use *ptr
ptr++;
}


This reads the string given by string_pool[index] till the end.



Note: To read a string using scanf, your code should be



scanf("%[^n]s", string_pool[index]);


EDIT: Hadn't noticed the allocation statement.



You need to assign memory individually for each string.
The code would be:



string_pool = malloc( sizeof(char *) * NO_STRS);
for(int i=0;i<NO_STRS; i++)
string_pool[i] = malloc(sizeof(char) * STR_LEN);






share|improve this answer














share|improve this answer



share|improve this answer








edited Jan 19 at 21:49

























answered Jan 19 at 21:27









Susmit AgrawalSusmit Agrawal

918513




918513













  • But first you must allocate some space for string_pool[index]

    – FredK
    Jan 19 at 21:33











  • Thats what i try to archieve but it doesnt work. I have to use &string_pool[index] then strlen works. The loop doesnt work at all.

    – StrangerThings
    Jan 19 at 21:33











  • No, it doesn't work. It is undefined behavior, which can seem to work, but you are overwriting core.

    – FredK
    Jan 19 at 21:35











  • I also thought so but its just not working. I have to use the pointer to get it working. maybe there is my problem. I declare char **stringpool in the global scope, does that matter?.

    – StrangerThings
    Jan 19 at 21:36











  • @Susmit Agrawal *string_pool[i] is of type char, not char*.

    – FredK
    Jan 19 at 21:46





















  • But first you must allocate some space for string_pool[index]

    – FredK
    Jan 19 at 21:33











  • Thats what i try to archieve but it doesnt work. I have to use &string_pool[index] then strlen works. The loop doesnt work at all.

    – StrangerThings
    Jan 19 at 21:33











  • No, it doesn't work. It is undefined behavior, which can seem to work, but you are overwriting core.

    – FredK
    Jan 19 at 21:35











  • I also thought so but its just not working. I have to use the pointer to get it working. maybe there is my problem. I declare char **stringpool in the global scope, does that matter?.

    – StrangerThings
    Jan 19 at 21:36











  • @Susmit Agrawal *string_pool[i] is of type char, not char*.

    – FredK
    Jan 19 at 21:46



















But first you must allocate some space for string_pool[index]

– FredK
Jan 19 at 21:33





But first you must allocate some space for string_pool[index]

– FredK
Jan 19 at 21:33













Thats what i try to archieve but it doesnt work. I have to use &string_pool[index] then strlen works. The loop doesnt work at all.

– StrangerThings
Jan 19 at 21:33





Thats what i try to archieve but it doesnt work. I have to use &string_pool[index] then strlen works. The loop doesnt work at all.

– StrangerThings
Jan 19 at 21:33













No, it doesn't work. It is undefined behavior, which can seem to work, but you are overwriting core.

– FredK
Jan 19 at 21:35





No, it doesn't work. It is undefined behavior, which can seem to work, but you are overwriting core.

– FredK
Jan 19 at 21:35













I also thought so but its just not working. I have to use the pointer to get it working. maybe there is my problem. I declare char **stringpool in the global scope, does that matter?.

– StrangerThings
Jan 19 at 21:36





I also thought so but its just not working. I have to use the pointer to get it working. maybe there is my problem. I declare char **stringpool in the global scope, does that matter?.

– StrangerThings
Jan 19 at 21:36













@Susmit Agrawal *string_pool[i] is of type char, not char*.

– FredK
Jan 19 at 21:46







@Susmit Agrawal *string_pool[i] is of type char, not char*.

– FredK
Jan 19 at 21:46




















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54271430%2fread-a-string-char-by-char-from-an-associative-pointer-array%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Liquibase includeAll doesn't find base path

How to use setInterval in EJS file?

Petrus Granier-Deferre