How to input a string in a 2d array in C? - c

If i want to take an input in a 2d array with each string in one row, and the next in the other(i.e. change the row on pressing enter). How can i do that in C. C doesnt seem to have convenient "String" Handling. I obviously mean doing so without the use of getchar().

3 ways are there which are mentioned below.
If you know the maximum number of strings and maximum number of chars, then you can use the below way to declare a 2D character array.
char strs[MAX_NO_OF_STRS][MAX_NO_CHARS] = {0};
for (i = 0; i < MAX_NO_OF_STRS; i++)
{
scanf("%s", strs[i]);
}
If you know the maximum number of strings, and you dont want to waste the memory by allocating memory for MAX_NO_CHARS for all strings. then go for array of char pointers.
char temp[MAX_NO_CHARS] = {0};
char *strs[MAX_NO_OF_STRS] = NULL;
for (i = 0; i < MAX_NO_OF_STRS; i++)
{
scanf("%s", temp);
strs[i] = strdup(temp);
}
If you know the maximum number of strings during run time means, you can declare a double pointer of char. Get the number of strings n from user and then allocate memory dynamically.
char temp[MAX_NO_CHARS] = {0};
char **strs = NULL;
int n = 0;
scanf("%d", &n);
strs = malloc(sizeof(char*) * n);
for (i = 0; i < n; i++)
{
scanf("%s", temp);
strs[i] = strdup(temp);
}

#include<stdio.h>
main()
{
char student_name[5][25];
int i;
for(i=0;i<5;i++)
{
printf("\nEnter a string %d: ",i+1);
scanf(" %[^\n]",student_name[i]);
}
}
u can read strings using 2d array without using getchar() by putting space in scanf(" %[^\n]")
; before %[^\n]!

An alternative to using malloc and filling up an array of pointers with buffers of a fixed size, would be to allocate a 2d array (in static storage or on the stack) and fill it up. KingsIndian modifed code example would than look like this:
#include <stdio.h>
int main()
{
char str[2][256] = {{0}};
int i = 0;
for(i=0;i<2;i++)
{
scanf("%255s", &str[i][0]);
}
return 0;
}
If all strings you expect to get are no longer than some size, than this approach will spare you the need to deal with freeing the memory yourself. It is less flexible however, meaning that you can't fit the size of an individual buffer to the string it contains.
EDIT
Adding to the information in the comment, to read a string that is terminated only by a new-line, rather than by any whitespace:
scanf("%255[^\n]", str[i]);

Related

Create an array of unknown strings - Undefined behaviour

In what way is the following code faulty or undefined behaviour?
I suggested this as a possibility to create an array of strings, if string number and size are unknown beforehand, and after a short discussion, it was suggested that I open a new question.
The following code produced the expected results when I compiled it with gcc, but that can happen in spite of undefined behaviour (it's undefined after all).
So, what is the mistake?
int n, i;
printf("How many strings? ");
scanf("%d", &n);
char *words[n];
for (i = 0; i < n; ++i) {
printf("Input %d. string: ", i + 1);
scanf("%s", &words[i]);
}
for (i = 0; i < n; ++i) {
printf("%s\n", &words[i]);
}
Edit:
I feel stupid now for missing this, I guess getting the correct answer back just made me miss my error. But that others may learn from my mistake:
I guess I got completely wrong what the & operator does. I thought it would give me where words points to, but of course it does the exact opposite. See the answers.
scanf("%s", &words[i]); and printf("%s\n", &words[i]); invokes *undefined behavior because data having wrong type are passed.
In both of scanf() and printf(), %s requires char* pointing at valid buffer but what is passed are char**.
Also don't forget to allocate buffer to store strings before reading.
Try this:
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int n, i;
printf("How many strings? ");
scanf("%d", &n);
char *words[n];
for (i = 0; i < n; ++i) {
printf("Input %d. string: ", i + 1);
words[i] = malloc(1024001); /* allocate enough buffer */
if (words[i] == NULL) {
perror("malloc");
return 1;
}
scanf("%1024000s", words[i]); /* limit length to read to avoid buffer overrun */
}
for (i = 0; i < n; ++i) {
printf("%s\n", words[i]);
}
for (i = 0; i < n; ++i) {
free(words[i]); /* clean what is allocated */
}
return 0;
}
char *words[n];
creates an array of uninitialized pointers
scanf("%s", foo);
writes values to the position foo is pointing to
it is not specified where the pointers of words are pointing to so they could point anywhere which could result in a segfault
next words is a char**
words[i] is a char *
&words[i] is a char **
%s expects a char* so it's again undefined behavior what happens
so you first have to initialize your words arrays using for example malloc and then write the values to words[i]
This:
char *word;
is a pointer, Before it is used as a container for say a string, it needs to point to memory sufficient for the string.
for example, this will work
word = malloc(80*sizeof(*word));
if(word)
{//success, continue
Similar to above, this:
char *word[n];
extension is an an array of n pointers. Before any of the pointers can be used as a container for say some strings, each needs to point to its own memory location. Assuming the value n has been scanned in, this will work:
for(int i=0;i<n;i++)
{
word[i] = malloc(80*sizeof(*word[i]));//80 for illustration
if(!word[i])
{//handle error...
Once the memory is allocated, the strings can be populated.
However, to ensure user input does not overflow the buffer defined by each instance of word, use a width specifier in the format string:
Change:
scanf("%s", &words[i]);
To:
scanf("%79s", words[i]);//note & is not needed as the symbol for a char array serves as the address
// ^^ ^

C - Creating an array of character arrays

I am trying to make an array of character Arrays. The program will read in sentences and store the sentences in a character array, and then that character array will be stored in another array. After reading numerous websites and Stack Over Flow pages I think it can be done like this. The program breaks when trying to store my character array into another array, so i'm not sure how to correct my code.
#include <stdio.h>
#include <math.h>
#include <time.h>
int main(int ac, char *av[])
{
int size; //number of sentences
char strings[100];// character array to hold the sentences
char temp;
printf("Number of Strings: ");
scanf_s("%d", &size); // read in the number of sentences to type
char **c = malloc(size); //array of character arrays
int i = 0;
int j = 0;
while (i < size) //loop for number of sentences
{
printf("Enter string %i ",(i+1));
scanf_s("%c", &temp); // temp statement to clear buffer
fgets(strings, 100, stdin);
// **** this next line breaks the program
c[i][j] = strings; // store sentence into array of character arrays
j++;
i++;
}
printf("The first character in element 0 is: %d\n", c[0][0]);
system("PAUSE");
return 0;
}
Al you need to do is allocate the memory for the string just read and copy the string:
c[i][j] = strings; // replace this with:
c[i]= malloc(strlen(strings)+1);
strcpy(c[i],strings);
Sadly char **c is not array of characters arrays. But this will properly allocate a 2d array dynamically if you follow
char (*c)[SIZE];
And then doing this
c = malloc(sizeof(char[LEN][SIZE]));
Then you do what you are trying to do.
for(size_t i = 0; i < LEN; i++){
if(fgets(c[i],SIZE,stdin)){
...
}
}
Or you can do it like this
char **c = malloc(LEN);
..
for(size_t i = 0; i < LEN; i++){
c[i] = malloc(SIZE);
...
}
But again c is nothing but jagged array of characters.
Check the return value of malloc and free the dynamically allocated memory when you are done working with it.
Listen dude,
Do you want to store the words in the character array and then store this in another array.
It is what you want ?
If yes then you can do the following.
Use stdlib by using # include <stdlib.h> .
This lets you use string functions directly.
Now read every word as a string and make array of strings.
So now if you number of strings is n, define an array for that as string my_array[n] and scan each word using scanf("%s",&my_array [i]).
In this way you will get an array of strings.

function to get words and put them in array

I need to write a C function that gets from the user the number of the words that he wants to enter, then the function has to scan the word from the user and but them in the array.
For example:
Program:
number of words:
User:
3
hi
my
name
(between every word there is enter) then the function has to put these words in
string array (the size of the array must be defined by malloc and the max size of the string is 100 (could be less)).
int main()
{
int n;
printf("Please enter the number of words: \n");
if (scanf("%d",&n)!=1)
return 0;
char *name;
name = malloc((sizeof(char)*100*n));
int c;
int i;
int m;
for (i = 0; i < n && ((c=getchar()) != EOF );i++)
{
name[i] = c;
}
finds_themin(&name, m); //I know this work
return 0;
}
You need to setup a pointer to pointer.
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main(){
char **s;
int n;
char buffer[64];
fgets(buffer,64,stdin);
n=strtol(buffer,NULL,10);// I avoid using scanf
s=(char **)malloc(sizeof(char*)*n);// you need to declare a pointer to pointer
/*
'PtP s' would look like this:
s[0]=a char pointer so this will point to an individual string
s[1]=a char pointer so this will point to an individual string
s[2]=a char pointer so this will point to an individual string
....
so you need to allocate memory for each pointer within s.
*/
int i;
for(i=0;i<n;i++){
s[i]=(char*)malloc(sizeof(char)*100);// length of each string is 100 in this case
}
for(i=0;i<n;i++){
fgets(s[i],100,stdin);
if(strlen(s[i])>=1){// to avoid undefined behavior in case of null byte input
if(s[i][strlen(s[i])-1]=='\n'){ // fgets also puts that newline character if the string is smaller than from max length,
s[i][strlen(s[i])-1]='\0'; // just removing that newline feed from each string
}
else{
while((getchar())!='\n'); //if the string in the command line was more than 100 chars you need to remove the remaining chars for next fgets
}
}
}
for(i=0;i<n;i++){
printf("\n%s",s[i]);
}
for(i=0;i<n;i++){
free(s[i]); //avoiding leaks
}
free(s);
}
As you need to store an array of strings you need an array of char* or char** to point each string (char array).
char **name;
name = malloc(n); // to store n strings.
Then in the loop use fgets to read the input as a line. Also, you need to allocate the memory for each new char array.
fflush(stdin);
for (i = 0; i < n; i++) {
name[i] = malloc(100); // allocating memory for string.
fgets (name[i], 100, stdin); // 100 is the max len
}
You can then simply iterate over the char** array, the ith index will point to the ith string.
for (i = 0; i < n; i++) {
// printf("%s", name[i]);
}

C - how to store multiple strings in an array

Wondering how store different strings in an array.
For example a user would input 'qwe' and the program would then store that in an array variable[0]. Entering another string would then store it as variable[1] and so on
int
main(int argc, char *argv[]) {
char variable[1000];
int i;
printf("enter a variable\n");
scanf("%s", variable);
for (i = 0; ??? ;i++) {
printf("The variable entered was: %s\n",variable[i]);
}
return 0;
Im new to C so I have no idea what im doing. but thats what I have came up with so far and was wondering if I could get some help with filling in the rest
Thanks!
You can use 2D array to store multiple strings. For 10 strings each of length 100
char variable[10][100];
printf("Enter Strings\n");
for (int i = 0; i < 10 ;i++)
scanf("%100s", variable[i]);
Better to use fgets to read string.
fgets(variable[i], sizeof(variable[i]), stdin);
You can also use dynamic memory allocation by using an array of pointers to char.
The most efficient way is to have an array of character pointers and allocate memory for them as needed:
char *strings[10];
int main(int ac, char *av[]) {
memset(strings, 0, 10 * sizeof(char *));
for (int i = 0; i < 10; i += 1) {
char ins[100];
scanf("%100s", ins);
strings[i] = malloc(strlen(ins) + 1);
if (strings[i]) {
strcpy(strings[i], ins);
}
}
}
variable[0] has just stored first letter of string. If you want to store multiple strings in an array you can use 2D array.
it has structure like
arr[3][100] = { "hello","world", "there"}
and you can access them as
printf("%s", arr[0]); one by one.
scanf returns number of successful readed parameters;
use 2D array for string-array
Never go out of bounds array
#include <stdio.h>
//Use defines or constants!
#define NUM_STRINGS 10
#define MAX_LENGTH_OFSTRING 1000
int main() {
char variable[NUM_STRINGS][MAX_LENGTH_OFSTRING +1 /*for '\0' Null Character */];
int i = 0;
printf("enter a variable\n");
while(scanf("%s", variable[i]) > 0){//if you print Ctrl+Z then program finish work. Do not write more than MAX_LENGTH_OFSTRING symbols
printf("The variable entered was: %s\n",variable[i]);
i++;
if(i >= NUM_STRINGS)
break;
}
return 0;
}

strings of characters in C

I am trying to solve a C problem where I have to sort n strings of characters using pointers.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void sort (char *s, int n)
{
int i,j; char aux[]="";
for (i=1;i<=n-1;i++)
{
for (j=i+1;j<=n;j++) //if s[i]> s[j] switch
{
if (strcmp(*(s+i),*(s+j))==1)
{
strcpy(aux,*(s+i);
strcpy(*(s+i),*(s+j));
strcpy(*(s+j),*(s+i));
}
}
}
}
void show(char *s, int n)
{
int i;
for (i=1;i<=n;i++)
{
printf("%s",*(s+i));
}
}
int main()
{
int i,n; char *s;
printf("give the number of strings:\n");
scanf("%d",&n);
s=(char*)calloc(n,sizeof(char));
for (i=1;i<=n;i++)
{
printf("s[%d]= ",i);
scanf("%s",s+i);
}
sort(s,n);
show(s,n);
return 0;
}
The warnings that I get are when I use strcmp to compare and when I use strcpy to switch *(s+i) and *(s+j) values.
"passing argument 2 of strcmp makes pointer from integer without a cast"
The warnings that I get are when I use strcmp to compare and when I use strcpy to switch *(s+i) and *(s+j) values.
"passing argument 2 of strcmp makes pointer from integer without a cast"
You are wrong argument to strcmp and strcpy. Signature of strcmp and strcpy are
int strcmp(char *string1, char *string2);
char *strcpy(char *dest, const char *src)
But you are passing it the arguments of char type. Removefrom(s+i)and*(s+j)`. It should be
if (strcmp((s+i), (s+j))==1)
{
strcpy(aux, (s+i));
strcpy((s+i), (s+j));
strcpy((s+j), (s+i));
}
Another problem is you have not allocated memory for the pointer s. For characters, you can declare it as
s = malloc ( (n + 1)*sizeof(char) );
or simply
s = malloc ( n + 1 ); // +1 is for string terminator '\0'
You seem to have mis-understood the return value of strcmp(); it's an integer that will be 0 (zero) if and only if the two string arguments are equal. You're testing for 1, which it will only be rarely; it has no specific meaning.
Consider just using qsort().
You're allocating space for n strings of 1 byte each. The easiest approach is to assume each string will be less than some set length, like 40 bytes. Then you would allocate the memory like this:
s=(char*)calloc(n*(40),sizeof(char));
Then your scanf needs to be modified:
scanf("%s",s+(i*40));
Now, string 1 will be at *s, string 2 will be at *(s+40), etc. Keep in mind that a string ends with a null character (0x00), so the string can only contain 39 chars. Any unused data will also be 0x00.
Do the same s+(i*40) for the sorting algorithm, compare to >0, not ==1, and strcmp, strcpy expect pointers. Then you should be good.
In your code there are a lots of mistakes: in variable declarations, memory allocation and pointer usage.
First remember that you should always reserve enough space to store your string values, and be aware to don't try to store a string with a length greater then the reserved space.
Also you should be very careful managing pointers (s+1 doesn't point to the first string but to the second one, s+n points out of the allocated memory)
So, as mentioned in other answers you should decide the maximum size of your strings an then allocate for them the right amount of memory.
Then I suggest you to use a pointer to strings, i.e. a char** to access your strings and manage the sort, in this way the code is more readable and the sort is faster (you don't need to copy strings, but only to switch pointers)
So your main function should be:
int main()
{
int i, n;
// Declare the pointer to the memory where allocate the space for the strings
char* a; // points to a char ( == is a string)
// Declare the pointer to the memory where store the pointer to the strings
char** s; // points to a char* ( == is a pointer to a string)
printf("give the number of strings:\n");
scanf("%d", &n);
// Allocate the memory for n strings of maximum 40 chars + one more for the null terminator
a=(char*)calloc(n*41, sizeof(char));
// Allocate memory for n pointers to a string
s=(char**)calloc(n, sizeof(char*));
// Notice the 0-based loop
for (i=0; i<n; i++)
{
s[i] = a + i*41; // set the i-th element of s to point the i*41-th char in a
printf("s[%d]= ", i);
scanf("%40s", s[i]); // read at least 40 characters in s[i],
// otherwise it will overflow the allocated size
// and could generate errors or dangerous side effects
}
sort(s,n);
show(s,n);
// Remember always to free the allocated memory
free(s);
free(a);
return 0;
}
the sort function sorts an array of pointers, without copying strings:
void sort (char** s, int n)
{
int i, j;
char* aux;
// Notice the 0-based loop
for (i=0; i<n; i++)
{
for (j=i+1; j<n; j++) //if s[i]> s[j] switch
{
if (strcmp(s[i], s[j])>0)
{
// You don't need to copy strings because you simply copy pointers
aux = s[i];
s[i] = s[j];
s[j] = aux;
}
}
}
}
finally the correct show function:
void show(char** s, int n)
{
int i;
// Notice the 0-based loop
for (i=0; i<n; i++)
{
printf("%s", s[i]);
}
}
I can't test the code but it should works
Added other options
1) If you have troubles with dynamic memory allocation you can use instead static allocation, your main function then will be:
int main()
{
int i, n;
// Declare an array of fixed lenght strings
char s[100][41]; // You manage max 100 strings
printf("give the number of strings:\n");
scanf("%d", &n);
// Ensure that n is less or equal maximum
if (n>100)
{
printf("you'll be asked for a maximum of 100 strings\n");
n=100;
}
// Notice the 0-based loop
for (i=0; i<n; i++)
{
printf("s[%d]= ", i);
scanf("%40s", s[i]); // read at least 40 characters in s[i],
// otherwise it will overflow the allocated size
// and could generate errors or dangerous side effects
}
sort(s,n);
show(s,n);
// You don't need to free any memory
return 0;
}
all other functions remain unchanged.
2) Whereas, if you want the maximum freedom in the memory you need you can choose a two allocate memory separately for each string only for the needed size, in this case your main funcion will be:
int main()
{
int i, n;
char buffer[1000]; // You need a buffer to read input, before known its actual size
// Declare the pointer to the memory where store the pointer to the strings
char** s; // points to a char* ( == is a pointer to a string)
printf("give the number of strings:\n");
scanf("%d", &n);
// Allocate memory for n pointers to a string
s=(char**)calloc(n, sizeof(char*));
// Notice the 0-based loop
for (i=0; i<n; i++)
{
printf("s[%d]= ", i);
scanf("%999s", buffer); // read at least 999 characters in buffer,
// otherwise it will overflow the allocated size
// and could generate errors or dangerous side effects
// Allocate only the memory you need to store the actual size of the string
s[i] = (char*)calloc(strlen(buffer)+1, sizeof(char)); // Remember always 1 more char for the null terminator
// Copy the buffer into the newly allocated string
strcpy(s[i], buffer);
}
sort(s,n);
show(s,n);
// Remember always to free the allocated memory
// Now you have first to free the memory allocated for each string
for (i=0; i<n; i++)
{
free(s[i]);
}
// Then you can free the memory allocated for the array of strings
free(s);
return 0;
}
all other functions remains unchanged too.

Resources