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.
Related
I don't understand Why don’t we have to print strings in for loop ? In normal cases we need to print arrays in for loop. For example, if we want to print the array of integers. It will be like this:
int a[n];
for (i = 0; i < n; i++){
printf("%d", a[i]);
}
But for strings like:
char s[100] = " Hello ";
printf("%s\n", s);
it is enough to write the name of array.
EDIT: It seems like I didnt ask my question properly as some of you wrote answers which is not related to my question.I edit my question.
Strings terminate with the empty character '\0', that's how it is possible to know when a string ends even without explicitly passing its length.
The difference is that C-style strings (which are char arrays) are zero-terminated, whereas int arrays are normally not zero terminated.
Theoretically, you could also create an int array which is zero-terminated and print that in a loop:
int a[] = {5,7,3,0};
for (i=0;a[i]!=0;i++)
{
printf("%d",a[i])
}
However, the problem with zero-terminated int arrays is that the number 0 could be a meaningful value, so you cannot be sure that it really is the end of the array when you encounter that value. With strings, however, the ASCII-Code 0 does not represent a meaningful value, so you can be reasonably sure that you have reached the end of the string.
Your example is far from analogous. %d refers to a single integer, while %s refers to an entire (but still single) string.
You are not passing the size of the array n[] to printf either - rather you are calling printf n times. You are printing one int just as you are printing one string.
The actual string length is not known a priori, rather printf iterates the string until it encounters the \0 terminator. Equivalent to:
for( int i = 0; s[i] != '\0'; i++)
{
printf( "%c", s[i] ) ;
}
because
char s[100] = " Hello ";
is equivalent to:
char s[100] = { ' ', 'H', 'e', 'l', 'l', 'o', ' ', '\0' } ;
Strings are multiple characters all at once. You cannot ask for a specific character from a string. If you want to do so, you must refer to it as an array of chars like this
for (i = 0; i < n; i++){
printf("%c", s[i]);
}
It is because you are already providing the parameter which is "%s" to the printf function which already has a definition telling it how to print a string.
Hope it helps.
One of the reason is that char only takes 1 byte of memeory and when you just press a character, the first index of array is filled up completely and it moves on to the next one till it encounters NULL character. This is not the case with integer array where the size is more than 1 byte and is machine dependent. So you cannot escape the first index by just pressing the number less than the maximum range. If you try to do this, it will store your numbers in first index only and hence a for loop is required there.
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;
}
So I want to do an encryption basically. The way I am doing this is creating two arrays and switching values. The problem I run into is, when the arrays are in just an array of characters, it doesnt work. But when I convert to the ASCII numbers, it does. Here's an example of what the two arrays would look like:
char* plainarray[26] = ["a","b","c"] //this would go on for the entire alphabet
char* cryptarray[26] = ["p","j","n"] //this array is the entire alphabet randomized
Then I have created to values for the plaintext and the encrypted text and values for the for loop. For example.
char plain[5] = "hello";
char* change[5] = {};
int i;
int j;
length = strlen(text); //length of string for for loop
Then I use two for loops to add encypted values to "crypt"
for(i=0; i<length; i++){
for (j = 0; j <26; j++){
if (plain[i] == plainarray1[j]){
change[i] = cryptarray2[j];
}
}
}
The warning code I get when compiling is:
warning: comparison between pointer and integer
One solution to my problem was using ASCII numbers in the plain text array and making it an int array. This compares the two characters, but the order of alphabet will be random for this problem, so I can't do that. Is there a better way to do this? Also I my array and assignment for the modified text ("change") proper? It doesn't give he right output.
You’re storing arrays of pointers to strings. Dereferencing your arrays of pointers gives you a pointer. To store an array of characters, write:
const char plainarray[26] = {'a', 'b', 'c', \* ... */ };
or
const char plainarray[] = "abc...";
The latter is not quite the same, because it has an extra byte at the end to terminate the string.
This type:
char* plainarray[26] = ...
is an array of pointers to characters, not an array of characters. Change it to this:
char* plainarray = "abc...";
Then, you can access the array like this:
printf("%c", plainarray[0]); // prints 'a'
You are comparing pointers to strings with ==, which is not correct since they are obviously all at different addresses.
If you did intend to store plainarray and cryptarray as arrays of pointers to null-terminated strings, each containing one letter of the alphabet, you can use the strcmp function to compare them (or, since every string pointed to is one character long plus the null-terminator, you can compare position [0] of both strings).
In my mind it makes more sense to store plainarray and cryptarray as arrays of plain char, however.
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.
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]);