This question already has answers here:
How to read string from keyboard using C?
(6 answers)
Closed 8 years ago.
I wanna write a program with an array of pointers to char where I store strings read from the console in it. A string is determined by \n. Any ideas how I can do this?
Code with mix of pseudocode so far:
char** arr;
arr = malloc(sizeof(char*) * 5);
arr = malloc(sizeof(char) * 10);
while (No \n read) {
// Store the string in the array
}
I really have no clue how to do this.
#include <stdio.h>
#include <stdlib.h>
int main(){
int i;
char **arr;
arr = malloc(sizeof(char*) * 5);//for 5 string
for(i=0;i<5;++i){
arr[i] = malloc(sizeof(char) * 10);//reserved storage space length 9
scanf("%9[^\n]%*c", arr[i]);//Read until \n, and discard \n
}
printf("\n");
//check print and free
for(i=0;i<5;++i){
puts(arr[i]);
free(arr[i]);
}
free(arr);
return 0;
}
int i, n;
char **arr;
arr = malloc(sizeof(char*) * 5);
for(i=0;i<5;++i){
arr[i] = malloc(sizeof(char) * 10);
}
i=0;
while(i<5 && 1==scanf("%9[^\n]%*c", arr[i]))
++i;
n = i;
printf("\n");
//check print
for(i=0;i<n;++i){
puts(arr[i]);
}
//deallocate
for(i=0;i<5;++i)
free(arr[i]);
free(arr);
You can use this one.
Creating the new char variable and allocate the memory for that. Then get the input like this.
p=(char *)malloc(100);
while ( (*p=getchar())!='\n')p++;
*arr[0]=p;
If you want to create the multiple lines then allocate the memory for that char variable dynamically then store that in the array of pointers.
Related
is there a simple one liner I can use in C to allocate arrays in (pointer of arrays)
This line creates 10 pointers of arrays
char *out[10];
I can't do this
char *out[100]=(char[10][100])malloc(sizeof(char)*10*100);
error: cast specifies array type
same error with
char *out[10]=(char*[10])malloc(sizeof(char)*10*100);
do I need to do it in loop like this
int main()
{
char *out[10];
int x=0;
while(x<10)
{
*(out+x)=malloc(sizeof(char)*100);// is this line correct?
x++;
}
*out[0]='x';
printf("%c\n",out[0][0]);
free(out);
return 0;
}
but this cause warning that
req.c:75:3: warning: attempt to free a non-heap object ‘out’ [-Wfree-nonheap-object]
75 | free(out);
so do I need to allocate and free each array in (array of pointers) in loop
Can't I do allocation and free arrays in array of pointer in one line instead of loop?
or is there anything thing in my loop wrong too
To allocate an array of pointers to strings, you need to do:
char** out = malloc(sizeof(char*[10]));
The whole point of using this form is that each pointer in that array of pointers can be allocated with individual size, as is common with strings. So it doesn't make sense to allocate such with a "one-liner", or you are using the wrong type for the task.
In case you don't need individual sizes but are rather looking for a char [10][100] 2D array with static size, then the correct way to allocate such is:
char (*out)[100] = malloc(sizeof(char[10][100]));
You can allocate the full array in one single step and have pointers inside that array:
char *out[10];
data = malloc(100); //sizeof(char) is 1 by definition
for (int x=0; x<10; x++) {
out[i] = data + x * 10;
}
*out[0] = 'x';
printf("%c\n",out[0][0]);
free(data); // you must free what has been allocated
int i;
char** out = (char**)malloc(sizeof(char*)*10);
for(i = 0; i<10;i++)
out[i] = (char*)malloc(sizeof(char)*100);
out[1][1] = 'a';
OR with same dimensions
#include <stdio.h>
#include <stdlib.h>
void main()
{
int r = 10, c = 100; //Taking number of Rows and Columns
char *ptr, count = 0, i;
ptr = (char*)malloc((r * c) * sizeof(char)); //Dynamically Allocating Memory
for (i = 0; i < r * c; i++)
{
ptr[i] = i + 1; //Giving value to the pointer and simultaneously printing it.
printf("%c ", ptr[i]);
if ((i + 1) % c == 0)
{
printf("\n");
}
}
free(ptr);
}
I have a question regarding the difference between char *<variable>[6] and char (*<variable>)[6].
I was making a code for an exercise which asks to input and store 6 strings and later turn each into an integer. My plan was to make an array of strings to store them and I did char *<variable>[6] = malloc(7*sizeof(char)); but an error showed up saying ' array initializer must be an initializer list ' but when i changed it to char (*<variable>)[6] = malloc(7*sizeof(char)); it can work properly. What is the difference between (*<variable>)[6] and *<variable>[6] ?
My code below:
#include <stdio.h>
#include <stdlib.h>
int main(void){
char (*sixString)m[6] = (char *) malloc(7 * sizeof(char));
int i;
int sum = 0;
for(i = 0; i < 6; i++){
printf("Input for the Number %d: ", i + 1);
scanf("%s", sixString[i]);
//fgets(sixString[i], 100, stdin);
printf("%s\n", sixString[i]);
sum = sum + atoi(sixString[i]);
}
float average = (float)sum/6 ;
printf("Sum is: %d\nAverage is: %.2f\n", sum, average);
free(sixString);
return 0;
}
char *<variable>[6]
is a 6-element array of char*.
char (*<variable>)[6]
is a pointer to 6-element array of char.
Your code allocated insufficient number of bytes. You should use
char (*sixString)[6] = malloc(7 * sizeof(char[6]));
or
char (*sixString)[6] = malloc(7 * sizeof(*sixString));
instead of
char (*sixString)m[6] = (char *) malloc(7 * sizeof(char));
(size is fixed and the extra m is removed)
Note that then you allocate 7 elements of char[6], but you use only 6 of them in the loop.
Allocating extra elements may look inefficient, but cause less harm than allocating insufficient size.
This question already has answers here:
Why does a C-Array have a wrong sizeof() value when it's passed to a function? [duplicate]
(6 answers)
Can I know char-array-size to which a char pointer variable points? [duplicate]
(5 answers)
Closed 6 years ago.
I want to count size of my array (how many values/indexes are there).
I've found something like this on StackOverflow
char **sentences;
while ((c = fgetc(fp)) != EOF) {
... fill the array...
}
size_t w = sizeof(sentences); // this is wrong! it returns size of pointer (memory)
It gives me "w = 4" but my array has 6 records.
I need this for "for loop" to print my results (tried to count every loop in "while", but I got it in different function and I don't know to return 2 values in array [count|array of strings]).
I will be happy for any idea how to print the whole array.
You can return your actual count like this:
#include <stdio.h>
#include <stdlib.h>
char **doSomething(size_t *count) {
char **sentences;
// Mock initialization of sentences, please skip :-)
sentences = (char **)calloc(13, sizeof(char *));
for (int i = 0; i < 13; i++) {
sentences[i] = (char *)calloc(8, sizeof(char));
sprintf(sentences[i], "quux-%d", i); // Just filling in some foobar here.
}
// ---------
*count = 13; // <-- Look here, we're dereferencing the pointer first.
return sentences;
}
int main(int argc, char **argv) {
size_t size;
char **res;
// Sending the address of size, so the function can write there.
res = doSomething(&size);
for(size_t i = 0; i < size; i++)
printf("res[%lu]: %s\n", i, res[i]); // You should see the filler outputted to stdout.
return 0;
}
I'm a noob so don't be hard on be.
Instead of something like this;
char string[NUM OF STRINGS][NUM OF LETTERS];
Is it possible to dynamically allocate how many strings will be in the array with malloc just like when you dynamically allocate memory for char pointer? Something like this:
int lines;
scanf("%d", &lines);
char *string[NUM OF LETTERS]
string = malloc(sizeof(char) * lines);
I tried it but it doesn't work; There must be something I'm doing wrong.
The other solution I thought of was:
int lines;
scanf("%d", &lines);
char string[lines][NUM OF LETTERS];
but I want to know if that's possible using malloc.
You can also use malloc for each word, like this
char **array;
int lines;
int i;
while (scanf("%d", &lines) != 1);
array = malloc(lines * sizeof(char *));
if (array != NULL)
{
for (i = 0 ; i < lines ; ++i)
{
int numberOfLetters;
while (scanf("%d", &numberOfLetters) != 1);
array[i] = malloc(numberOfLetters);
}
}
where numberOfStrings and lengthOfStrings[i] are integers that represent the number of strings you want the array to contain, an the length of the ith string in the array respectively.
You have two methods to implement this.
First is more complicated, cause it requires the allocation of memory for array of pointers to strings, and also allocation of memory for each string.
You can allocate the memory for entire array:
char (*array)[NUM_OF_LETTERS]; // Pointer to char's array with size NUM_OF_LETTERS
scanf("%d", &lines);
array = malloc(lines * NUM_OF_LETTERS);
. . .
array[0] = "First string\n";
array[1] = "Second string\n";
// And so on;
A disadvantage of the second method is that NUM_OF_LETTERS bytes are allocated for each string. So if you has many short strings, the first method would be better for you.
In case you want contiguous memory allocation:
char **string = malloc(nlines * sizeof(char *));
string[0] = malloc(nlines * nletters);
for(i = 1; i < nlines; i++)
string[i] = string[0] + i * nletters;
For more detailed explanation: Read FAQ list · Question 6.16.
int lines;
scanf("%d", &lines);
char (*string)[NUM OF LETTERS]
string = malloc(sizeof(*string) * lines);
char **ptop;
int iStud;
int i;
printf("Enter No. of Students: ");
scanf("%d",&iStud);
ptop=(char **) malloc(sizeof(char)*iStud);
flushall();
for(i=0;i<iStud;i++)
{
ptop[i]=(char *) malloc(sizeof(char)*50);
gets(ptop[i]);
}
for(i=0;i<iStud;i++)
{
puts(ptop[i]);
}
free(ptop);
I am still new with C and I am trying to empty a 2d char array. Here is the declaration:
char arg_array = (char**)calloc(strlen(buf), sizeof (char**));
for(i = 0; i<(strlen(buf)); i++)
{
arg_array[i] = (char*) calloc (strlen(buf), sizeof(char*));
}
Here is where I try to empty it:
void make_empty(char **arg_array)
{
int i;
for(i = 0; i <= BUFSIZ; i++)
{
arg_array[i][0] = '\0';
}
return;
}
Any help is appreciated
So, am I doing it right because this seems to give me segfaults when I try to add data to the array again and then print it?
Empty is just to have it empty - how can I explain more? lol
Try this:
void make_empty(char **arg_array, int rows, int cols)
{
int i,j;
for(i = 0; i <rows; i++)
{
for(j=0; j<cols;j++)
{
arg_array[i][j] = '\0';
}
}
return;
}
Where rows is number of rows and cols number of cols of your array.
P.S. This function clears the whole array as you should always do. As I commented before, putting '\0' as a first char in string does not clear the whole row, it only makes the rest of it ,,invisible'' for functions like printf. Check this link for more information: http://cplusplus.com/reference/clibrary/cstdio/printf/
There is no need to empty it. Often in C, memory allocation is done with malloc which simply returns to you a block of memory which is deemed owned by the caller. When calloc is called, as well as returning you a block of memory, the memory is guaranteed to be initialized to 0. This means for all intents and purposes it is already 'empty'.
Also I'm not quite sure if your code does what you are intending. Let me explain what it does at the moment:
char arg_array = (char**)calloc(strlen(buf), sizeof (char**));
This line is simply wrong. In C, there is no need to cast pointers returned from calloc because they are of type void *, which is implicitly casted to any other pointer type. In this case, you are storing it in a char type which makes no sense. If you do this:
char ** arg_array = calloc(strlen(buf), sizeof (char**));
Then it allocates an array of pointers of strlen(buf) length. So if buf is "hello" then you have now allocated an array which can store 5 pointers.
for(i = 0; i<(strlen(buf)); i++)
{
arg_array[i] = calloc (strlen(buf), sizeof(char*));
}
Again, I have removed the redundant cast. What this does is populates the array allocated earlier. Each index of the array now points to a char string of strlen(buf) * sizeof(char *) length. This is probably not what you want.
Your question is more clear to me now. It appears you want to remove the strings after populating them. You can do it two ways:
Either free each of the pointers and allocate more space later as you did before
Or set the first character of each of the strings to a null character
To free the pointers:
for(i = 0; i<(strlen(buf)); i++)
{
free(arg_array[i]);
}
To set the first character of each string to a null character:
for(i = 0; i<(strlen(buf)); i++)
{
arg_array[i][0] = '\0';
}
That is the same code as what you have originally and should be fine.
As proof, the following code will run without errors:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main(void)
{
char * buf = "hello";
char ** arg_array = calloc(strlen(buf), sizeof (char**));
unsigned int i;
for(i = 0; i < strlen(buf); i++) {
arg_array[i] = calloc(strlen(buf),
sizeof(char *));
}
for(i = 0; i < strlen(buf); i++) {
arg_array[i][0] = '\0';
}
for(i = 0; i < strlen(buf); i++) {
free(arg_array[i]);
}
free(arg_array);
return EXIT_SUCCESS;
}
If your code is segfaulting, the problem is coming from somewhere else. Did you overwrite the arg_array variable? Are you sure BUFSIZE is equal to strlen(buf)?