3

I'm new to C (coming from Java) and naturally that poses some difficulties. I would like to write just a short program that reads in char-Arrays from stdin and stores the individual strings in an array. After reading in the strings I just want to have them printed out, but that's when it gets really confusing for me. Here's my code:

#include <stdlib.h>
#include <stdio.h>


int main(){

char **stringarray[2];
char buffer[5];
int i = 0;
while( i < 2 && fgets(buffer, 5, stdin) != NULL){
    char *tmp = buffer;
    stringarray[i] = &tmp;
    i++;
}

for(int i = 0; i < 2; i++){
    printf("%s\n", &stringarray[i]);

}

return 0;
}

The first part does in fact compiles (i.e. the part before the print out). I understand that my stringArray has to be an array of char pointers, because that's what a char array basically is in c. It's a pointer to the first character. At first I just wrote

while( i < 2 && fgets(buffer, 5, stdin) != NULL){
    stringarray[i] = buffer;
    i++;
}

which also compiled, but of course then I have one pointer that points to buffer, which will only save the last string that has been read. What do I have to do that I can store a simple array of strings?

Curtis
  • 65
  • 1
  • 1
  • 8
  • 1
    You don't need an [array of pointers to pointers](http://c2.com/cgi/wiki?ThreeStarProgrammer) for this. An array of pointers would be enough. – Fred Foo May 02 '14 at 12:14
  • In your `printf("%s\n", &stringarray[i])`, you're taking *the address* (&-operator) of the i-th element. That's certainly not what you want. – lethal-guitar May 02 '14 at 12:20
  • Ok, I changed it again, but I still have the problem that I don't know how permanently store what buffer points to during one iteration of the loop. – Curtis May 02 '14 at 12:21
  • the adress-operator was there by accident. Sorry for the extra confusion – Curtis May 02 '14 at 12:25

3 Answers3

2

I suggest you change your code as following.

#include <stdlib.h>
#include <stdio.h>
#include <string.h> /* to use strdup function */


int main(){

char *stringarray[2]; /* I don't understand why you use pointer to pointer than pointer, char **stringarray[2]; */
char buffer[6]; /* I suggest 6 than 5, because string has terminate byte in C */
int i = 0;
while( i < 2 && fgets(buffer, 5, stdin) != NULL){
    stringarray[i] = strndup(buffer, 5);
    i++;
}

for(int i = 0; i < 2; i++){
    printf("%s\n", stringarray[i]); /* changed stringarray */

}

return 0;
}
xiaodongjie
  • 246
  • 2
  • 5
  • `strndup` is not standard if im not mistaken. It duplicates string (allocates memory and copies the original string into it), in java you don't have to think of memory, but in `C` `stringarray[i] = buffer` is only `address` assignment, meaning all elemnts of `stringarray` will point to the same buffer at the end of the loop – Dabo May 02 '14 at 12:44
2

char **stringarray[2]; is like char ***stringarray because an array is like a pointer to the first value of the array.

printf wants a char* and &stringarray[i] is a char**

if a string is an array then an array of strings is an array of array.

So the code is :

 int main()
{
    char stringarray[2][5];//array of (array of char)
    char buffer[5];
    int i = 0;
    while( i < 2 && fgets(buffer, 5, stdin) != NULL)
    {
        strcpy(stringarray[i],buffer); //copies the buffer into the string array
        i++;
    }

    for(i = 0; i < 2; i++)
    {
        printf("%s\n", stringarray[i]);

    }
    return 0;
}

If you didn't want to use buffer you could just writte :

    while( i < 2 && fgets(stringarray[i], 5, stdin) != NULL)
    {
        i++;
    }

Note that you get 5 characters, the last one will be the NUL terminator \0. And because you have to press enter to validate, the one before \0 will be Line Feed\n. And you will only have 3 characters you really wanted.

Heckel
  • 428
  • 9
  • 23
  • defenitly no, don't delete. But [arrays are not pointers](https://www.cs.bu.edu/teaching/cpp/string/array-vs-ptr/) – Dabo May 02 '14 at 13:03
  • I can't access to your link :(. I have always thought that arrays allocate a number of variables and kept the pointer to the first. I will do some reseach, thank you. – Heckel May 02 '14 at 13:08
0

You can do it using dynamic allocation technique as below .

#include<stdio.h>
#include<malloc.h>
#include <stdlib.h>
int main()
{
   int num;
   int len=0;
   int i;
   printf("Enter the number of elements to be entered ");
   scanf("%d",&num);

   //Allocate memory for the array of strings 
   char **var=(char **)malloc(num * sizeof(char *));

   for(i=0;i<num;i++)
   {
      printf("Enter the string   : ");
      //get strings using getline 
      getline(&var[i],&len,stdin); 

   }
    for(i=0;i<num;i++)
   {
      printf("String %d   : %s \n",i,var[i]);


   }

    free(var);

}
Santhosh Pai
  • 2,535
  • 8
  • 28
  • 49