Print multidimensional array in c - c

I'm trying to create a multidimensional array to keep strings in it, with a length of 5. However it seems to be problem when i try to print out a sinle element from the arrays.
In my printf("%s", a[0][0][5]) it should print out "hej0" in a char array last [5]stand for the amout of characters of the current element + '\o' And first and second [] stand for row and which element to target?
When i try to compile this code it will just crash.
int main() {
char a[3][4][5] = {
{"hej0", "hej1", "hej2", "hej3"} ,
{"hej4", "hej5", "hej6", "hej7"} ,
{"hej8", "hej9", "hej10", "hej11"}
};
printf("%s", a[0][0][5]);
return 0;
}

If you do :
printf("%s", a[0][0][5]);
You are trying to access the 6th character of the string pointed by a[0][0], which is "hej0".
It has 4 characters and the fifth is the NULL terminating byte \0 (so you are trying to read beyond the string).
To print "hej0":
printf("%s", a[0][0]);

First issue I have seen your code is that size of array should be a[3][4][6] not a[3][4][5].
Because your elements "hej10", "hej11" required 6 bytes instead of 5.
Also to print any particular element just provide base address like:
printf("%s", a[0][0]);

First problem is, if you want to put a 5 char string into a char array, you need to make the array 6 chars big, as it is terminated by character '\0'.
Second problem is, a[0][0][5] is the sixth element of the third row, which does not exist.
Third problem would be, if you want to print the complete string you should not specify a char number for output. Try a[0][0] instead of a[0][0][5]
Here is a correction:
char a[3][4][6] = {
{ "hej0", "hej1", "hej2", "hej3" },
{ "hej4", "hej5", "hej6", "hej7" },
{ "hej8", "hej9", "hej10", "hej11"}
};
printf("%s", a[0][0]);

Related

How do I print the contents of an array of strings?

I have created and initialized an array with the following strings:
char print_names[][10] = {"\t\t1. John\n",
"\t\t2. Smith\n",
"\t\t3. Jane\n",
"\t\t4. Mary\n",
"\t\t5. Lisa\n"};
As far as I know, the name of the array is a pointer itself. so when I put these lines:
printf("%c", *print_names[0]);
printf("%c", *print_names[1]);
It should point to the content of the that array element. But nothing is printed out on the console.
I went into the debugger and it clearly shows that each element holds the appropriate string. I'm not sure where I did wrong.
EDIT: I'm still learning the basic about array and pointer, so I didn't include <string.h> in the file.
Additional question: is it possible to print the content (the names) without using string?
OK. I figured it out. I think I understand now. Thanks for answering.
*print_names[0] is equal to print_names[0][0]. It's the first character of the first string in print_names.
And as the first character of every string in the print_names array is a tab ('\t') you print this tab which isn't really visible.
If you want to print the string itself you need to use %s as the format, and pass a pointer to the first character. Which can be done as:
printf("%s", print_names[0]);
On the other hand, if you want to print the tab, and make it seen, then surround the output with other characters. Like
printf("tab = \"%c\"\n", print_names[0][0]);
which will print the tab surrounded by double quotes.
The array print_names has 2 dimensions:
the number of elements is determined from the initializer: 5 in your example
the number of char elements in each element in the array is defined to 10.
The problem is 5 of the initializers have exactly 10 characters and one has 11 characters. The initializer is inconsistent with the object definition and none of the elements are null terminated strings.
You should change the width to at least 12 and you can use printf() to print the array elements this way:
#include <stdio.h>
void print_array() {
char print_names[][12] = {
"\t\t1. John\n",
"\t\t2. Smith\n",
"\t\t3. Jane\n",
"\t\t4. Mary\n",
"\t\t5. Lisa\n"
};
size_t count = sizeof(print_names) / sizeof(print_names[0]);
for (size_t i = 0; i < count; i++) {
printf("%s", print_names[i]);
}
}
Regarding your approach:
As far as I know, the name of the array is a pointer itself.
Not really: the name of the array just that. When you use the name of an array in an expression other than sizeof(n), it decays into a pointer to the first element of the array.
The lines below output the first byte of the first and second strings:
printf("%c", *print_names[0]); // same as print_names[0][0]
printf("%c", *print_names[1]); // same as print_names[1][0]
As you have overdimensioned the array (with 10 entries, but you have only filled 5, the others are filled with NULL pointers) you can print the array contents (one string per line) with:
char **p;
for (p = print_names; *p; p++)
printf("%s", *p);
which is equivalent to this code:
int i;
for (i = 0; print_names[i]; i++)
printf("%s", print_names[i]);
of if you know that there are 5 elements in the array:
int i;
for (i = 0; i < 5; i++)
printf("%s", print_names[i]);
It works ,but because the first element of each row is \t you won't see any thing you can also use
printf("%s", print_names[0])
to print : \t\t1. John\n
this row.
notice you're placing more than 10 characters in second dimension of your array.

Array pointer issue in C - array only contains last value

I'm trying to add (well, append really) the letters in the alphabet to an empty char array. However, I appear to run into some sort of pointer issue I don't understand, as my array contains only the last character. I tried moving the letter char outside of the for loop, but the compiler didn't like that. I also looked on here about how to create a list of all alphabetical chars, and one of the better answers was to type them all in 1 at a time. However, my problem means I don't fully understand for loops and pointers in C, and I want to.
#include <stdio.h>
int main(void) {
char *empty_list[26];
for (int i = 0; i < 26; i++){
char letter = i + 65;
empty_list[i] = &letter;
}
printf("%s", *empty_list);
return 0;
}
The main problem is your declaration:
char *empty_list[26];
defines an array of 26 pointers to characters. In your current code you assign each element in the array the address of the variable letter. Since that is out of scope when you print it is luck that it prints out the last one, it could equally have printed out garbage or crashed if the code between was complex. It could also have printed out additional garbage after the letter with what you already have since there is no way of knowing whether there is a string terminating character (\0) after the letter. In your existing code printf("%s", *empty_list); prints the first pointer from the array as a null terminated string, which if you ignore the loss of scope and assume the memory contents are still around, will be the last value from the loop since all pointers in your array point to the memory that letter was stored at and that memory has the last value from the loop.
If your intention was to create an array with the letters then it should be:
char empty_list[27];
It needs to be 27 as you need to leave space for the string terminating character at the end. One way to fill that in would be to use:
empty_list[26] = '\0';
after the end of your for loop and before you print the contents of the array (do not include the asterisk here - because it is an array the compiler will automatically take the address of the first element):
printf("%s", empty_list);
As brothir mentioned in the comments when you assign the value of the letter to the element in the array it should be without the ampersand:
empty_list[i] = letter;
There are a few things wrong with your code.
Firstly, the type of empty_list is presently an array of pointers to char, when it really should be an array of char, since your intent is to print it out as if it were the latter in the call to printf after your loop. char empty_list[26]; is the correct declaration.
Secondly, in your loop, you assign &letter when all you need is letter. Heck, you don't even need the intermediate variable letter. Just empty_list[i] = i + 'A'; will suffice.
Lastly, you are passing empty_list to printf to satisfy a format specifier %s, which expects a null-terminated string. What you need to do is add another element to empty_list and set that to zero:
char empty_list[27];
// populated 0..25 with 'A'..'Z' in your code...
empty_list[26] = '\0';
printf("%s\n", empty_list);
// Output: ABC...Z
With the above help (much appreciated), my working code to create an array of letters in C is below:
#include <stdio.h>
int main(void) {
// create an array with 1 extra space for null terminator
char empty_list[27];
// add null terminator so string knows when it's finished.
empty_list[26] = '\0';
for (int i = 0; i < 26; i++){
// add 65 to get ASCII value for 'A'
char letter = A + i;
// insert each char into the array sequentially
empty_list[i] = letter;
}
printf("%s", empty_list);
return 0;
}

Why this code can't print characters in an array?

I compiled this code using gcc (tdm-1) 5.1.0 and please tell me why the output doesn't contain "hello"
#include<stdio.h>
void main()
{
int i;
char st[20];
printf("Enter a string ");
scanf("%s",st);
for(i=0;i<20;i++)
{
printf("%c",st[i]);
}
}
Input:hello
Output: # #
You print all 20 elements of the array, but if the user entered a string smaller than that not all elements would be initialized. They would be indeterminate and seemingly random.
Remember that char strings in C are really called null-terminated byte strings. That null-terminated bit is important, and mean you can easily find the end of the string by checking the current character agains '\0' (which is the terminator character).
Or you could just use the strlen function to get the length of the string instead:
for(i=0;i<strlen(st);i++) { ... }
Or use the "%s" format to print the string:
printf("%s", st);
Also note that without any protection the scanf function will allow you give longer input than is space for in the array, so you need to protect agains that, for example by limiting the amount of characters scanf will read:
scanf("%19s",st); // Write at most 19 character (*plus* terminator) to the string
Now for why your input doesn't seem to be printed, it's because the indeterminate contents of the uninitialized elements. While you're not going out of bounds of your array, you still go out of bounds of the actual string. Going out of bounds leads to undefined behavior.
What's probably is happening is that some of the "random" indeterminate contents happens to be a carriage return '\r', which moves the cursor to the start of the line and the output already written will be overwritten by the uninitialized elements in your array.
Here's a short example as Qubit already explained:
#include <stdio.h>
void main () {
char str1[20];
printf("Enter name: ");
scanf("%s", str1);
printf("Entered Name: %s", str1);
}
Here
char st[20];
st is a local variable & default array st contents are garbage not zero. So if you scan less than 20 characters into st, in that case remaining location of array st contains garbage, hence it's printing some junk data like # # in case of
char st[20];
printf("Enter a string ");
scanf("%s",st);
for(i=0;i<20;i++) {
printf("%c",st[i]);
}
& it's a bad practice as if user entered few char lets say 5 char, then your loop rotates 20 times, internally it will do more operations or consume more CPU cycle.
So if you want to print a char array char by char, then you should rotate a loop until \0 char encounters, for e.g
for(i=0;st[i];i++) { /* this fails when \0 encounters */
printf("%c",st[i]);
}
Or
as others suggested you can print char array st using single printf by using %s format specifier like
printf("%s\n",st); /*here printf starts printing from base address of st
and prints until \0 */
Also it's better to initialize char array st while declaring itself. for e.g
char st[20] ="";

How to check each character in a dynamically allocated string array, in C?

So what I am trying to ultimately do is search an array for a name, and if the name is found return that name. Well, to do that I need to check for each character in every row and column for a match. And before I could do that I need to know exactly how to go about doing that, so I am trying to figure out how to get the dynamic array to print out the first character, then second and so on in order to compare it with the name being searched. But I am having trouble doing this. So my question is how would I go about checking each character in such an array? I've let out most parts of the code but I think I included the main parts that I am troubled in. Thanks for the help in advance.
I'm a beginner in C, so sorry if I did anything gravely wrong, thanks!
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#define STRINGSIZE 20
int main(){
char **firstNames, **lastNames;
int classSize,i;
char sample[21] = "Slack";
printf("Please indicate number of records you want to enter (min 5, max 15):\n");
scanf("%d", &classSize);
firstNames=malloc(classSize*sizeof(char*));
for (i=0; i<classSize; i++) {
firstNames[i]=malloc(STRINGSIZE*sizeof(char));
}
printf("Please input records of students (enter a new line after each record), with following format: first name");
*firstNames="Slack";
printf("\n\n");
printf("%c", *(sample)); //Will print out S
printf("%c", **firstNames); //Will print out S
printf("%c", *(sample+1)); //Will print out l
printf("%c", **(firstNames+1)); //Will give error
printf("%c", **(firstNames)+1); //Will print T (Next ascii char after 'S'
printf("%c", **((firstNames)+1)); //Will give error
}
A C string is an array of characters. Even if dynamically allocated, you can treat it as such, so:
sample[0]; // S
sample[1]; // l
sample[2]; // a
// etc
You are storing multiple pointers to C strings in firstNames. You access it as an array:
firstNames[0]; // first name
firstNames[1]; // second name
firstNames[2]; // third name
// etc.
Now you just combine these, as firstName[0] is just a C string, just like sample:
firstName[0][0]; // first letter in first name
firstName[0][1]; // second letter in first name
firstName[1][0]; // first letter in second na,e
// etc.
You have an array of pointers to char firstNames the size of classSize. Every pointer in this array points to valid memory you allocated with malloc.
The error you make is assigning a string literal to the first pointer of the array firstNames, overwriting the pointer with the address of the string literal. This will lose the memory you allocated and also the string literal cannot be modified, which you do later causing the program to crash.
This line will copy a string "Slack" to the memory the first pointer in the array points to:
strcpy( firstNames[0] , "Slack" ) ; //make sure you have enough space
Note that firstNames[0] equals to *firstNames.
i used in the for loop is not defined anywhere.

Undefined behavior of a program

While writing a program i am filling the entries of a char array with digits. After doing so the length calculated for an array having no zero is correct but for an array starting with zero is zero!
Why is this result coming so!I am not able to interpret my mistake!?
int main()
{
int number_of_terms,no,j,i;
char arr[100];
char c;
scanf("%d",&number_of_terms);
for(i=0;i<number_of_terms;i++)
{
j=0;
while(c!='\n')
{
scanf("%d",&arr[j]);
if(c=getchar()=='\n')
break;
j++;
}
printf("Length is:%d\n",strlen(arr));
}
return 0;
}
for eg if i input my array elements as 4 5
lenght is 2
and if my array elements as 0 5
length is 0..
You are using "%d" in your format specifier, which produces an integer, and you are passing in the address of a character array. This is, exactly like your title says, undefined behaviour. In particular, the value zero will take up 4 of the cells in your string, and will write zero to all of those. Since the character with value zero is the end marker, you get zero length string. However, on another architecture, the second character would probably cause a crash...
If you want to store integers in an array, you should use int arr[...];. If you want to store characters, use "%c".
You are copying the value 0 into the array. This eqals the character '\0' which is used to terminate strings. What you want is to copy the character '0' (has the value 48, see an ascii table).
Change %d to %c to interpret the input has character instead of decimal.
scanf("%c",&arr[j]);
Also your "string" in arr is not zero terminated. After all the characters of your string, you have to end the string with the value 0 (here a decimal is correct). strlen needs it, because it determines the length of the string by traversing the array and counting up until it finds a 0.

Resources