compare two char in C without ASCII - c

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.

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.

Why don’t we need for loop to print strings in C?

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.

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;
}

How to change characters within an array of strings?

I'm quite new to C and as part of my task, I must remove the the newline character that is added at the end of a string using fgets().
My lecturer advised this method:
char names[20];
fgets(names,20,fp);
names[strlen(names)-1]='\0';
I've omitted some of the code as I'm only demonstrating the method.
However, in our task, we have to deal with arrays of strings.
I've tried...
names[strlen(names[i])-1]='\0';
but seems to only find the length of the string, deduct 1 and then use that number in the index which then sets a string further down the array to \0
Is there a way to access the individual characters of the strings?
I know I can access the strings using
names[i] // where i is the numeric index
but I need to access the individual characters within that string.
This is my first time posting on StackOverflow so please inform me if I haven't included enough detail or have formatted my question poorly.
Thanks in advance.
As noted, in C a string is an array of characters. So, you can access the individual characters like you access any array. For your task what you need to do is
char names[100][20];
//Now this declares 100 strings of size 20 each.
//To access a single character in the position '4' from string 0 you can write
printf("%c",names[0][3]);
//To modify the string in position 'i' you will use
names[i][strlen(names[i])-1]='\0';
The last line is very similar to what you have written for a single string.
With the first index 'i' you access the string in that position. and with the second index you access a particular character of that string.
Try this:
#include <stdio.h>
#include <string.h>
int main(void)
{
char names[10][10];
char c = 'A';
for(int index = 0; i < strlen(names) - 1)
{
names[0][index] = c++;
}
names[i][strlen(names[i])-1]='\0';
printf("%s", namws[0]);
return 0;
}
In c, string is actually an array of char.
So,
char[] charArray = "string";
charArray[0] will give you 's'.

Using atoi to fill an array of ints

First time asking a question on here. Apologies if there's already threads about this but i had a few searches and didn't quite find what i think i was looking for. I'm very new to C and am working through a few homework exercises for my microcontroller systems class. We're currently working through easy exercises before we get into embedded C and I'm trying to write a program that'll take a line of text consisting of 10 numbers separated by commas and fill an array of ints with it. As a hint we were told to use a substring and atoi. I think i'm close to getting it right but i can't get it to output my numbers properly.
Also i'm not looking spoon fed answers. A few hints would suffice for now. I'd like to try figuring it out myself before asking for the solution.
Here is my code:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int a[10];
char str[] = {1,2,3,4,5,6,7,8,9,10}; //contains string of numbers
int i;
puts("This prints out ten numbers:");
for (i = 0; i < 10; i++)
{
a[i] = atoi(str);
printf("%d", a[i]);
//i'm guessing the problem lies in one of the above two lines
}
return 0;
}
This is outputting the following:
This prints out ten numbers:
0000000000
Thanks to anyone that can help!
Chris
You said that you have to use a line of text separated by commas but you've actually declared a char array containing ten (binary) integers. To get that into a string you just need to do this:
char str[] = "1,2,3,4,5,6,7,8,9,10";
Then you'll need someway to process this string to get each number out and into your array of int.
First off, you should declare a string as follows:
char str[] = {"1,2,3,4,5,6,7,8,9,10"};
the " made the numbers a whole string. Next, you'll need to tokenize them and using the <string.h> library which will come quite handy in this situation.
Here is how you do tokenizing:
define a token buffer first:
char* token;
token = strtok(str,","); //think of it as substring, the part of the str before the comma
for (i = 0; i < 10; i++)
{
a[i] = atoi(token);
printf("%d\t", a[i]);
//i'm guessing the problem lies in one of the above two lines
token = strtok(NULL, ","); //this line is also required for tokenizing the next element
}
Using the strtok() function, you separated the elements between the comas, and got yourself the number strings. Used atoi() function to convert them into integers and printed them. You can see this reference for strtok() function for better understanding.
The problem lies in how you're creating the string.
Please excuse my previous answer, I misunderstood your question:
Simply put, the declaration should be as follows:
char str[] = "1,2,3,4,5,6,7,8,9, 10, 12";
Next, you can use strtok to separate the string into an array of strings omittied the separator (which is in your case the comma), then pass the array members to atoi
Now, why is your code not working?
First, characters should be surrounded by the apostrophes or else the compiler will take the number you pass literally as the ASCII value.
Second, arrays in C like this:
char str[] = {'1', '2', '3', '4', '5'}; don't mean a comma separated string, these commas separate the ARRAY members, each in its own index and not as a whole string.
Your definition of char str[] = {1,2,3,4,5,6,7,8,9,10}; actually sets
the values of the chars to 1 to 10.
In the ASCII-chart of characters, these are unprintable control-characters.
Writing '1' instead of 1 will set the value to the ASCII-value of 1, which is 0x31.
another mistake is that the commas in your definition only seperate the values in the definition, so the result is a array of chars without any seperation, so 12345678910.
so the correct way would be
char str[] = "1,2,3,4,5,6,7,8,9,10";

Resources