Related
so I have been trying to write a code that displays different messages if different keys are pressed
It should display "Your hair looks nice" if one of the characters of the string is pressed and display "You look like your mom" if any number of symbol is pessedd (anything other than the array's elements)
what is the issue here?
(Mind the messages in the code I'm trying to stay chill so I picked random messages)
the code:
#include<stdio.h>
int
main ()
{
char i,o;
char a[54] =
{ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'g', 'k', 'l', 'm', 'n',
'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C',
'D',
'E', 'F', 'G', 'H', 'I', 'G', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
'T',
'U', 'V', 'W', 'X', 'Y', 'Z'
};
if (scanf ("%c", &o) == a[i])
printf ("Your hair looks nice");
else
printf ("You look like your mom");
return 0;
}
C have a set of standard character classification functions, like for example isalpha to check if a character is a letter or not.
With this you can make your program much simpler, and don't need the array:
#include <stdio.h>
#include <ctype.h>
int main(void)
{
int ch = getc(); // Read one character
if (isalpha(c))
{
puts("Your hair looks nice.");
}
else
{
puts("You look like your mom!");
}
}
Note that I use the getc function to read a character instead. In most cases scanf shouldn't really be used for input, it's use is unfortunately more non-trivial than the beginners guides and tutorials make it seem.
You need to check all relevant values of i. Currently, you don't even assign a single value to i, but you need to assign 54 different values in turn.
And of course, you need to call scanf only once, not 54 times.
If you want to see whether the inputted character is in the array, then you must compare that character with all 54 characters in the array. However, in your posted code, you are only making one comparison. I suggest that you use a for loop for doing the 54 comparisons. You can do one comparison per loop iteration.
Here is an example:
#include <stdio.h>
#include <stdlib.h>
int main( void )
{
char a[54] = {
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'g', 'k', 'l', 'm',
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'G', 'K', 'L', 'M',
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'
};
char input;
//get input character
if ( scanf( "%c", &input ) != 1 )
{
fprintf( stderr, "Input error!\n" );
exit( EXIT_FAILURE );
}
//determine whether input character is in array
for ( int i = 0; i < 54; i++ )
{
if ( a[i] == input )
{
printf( "Found character in array.\n" );
return 0;
}
}
printf( "Did not find character in array.\n" );
return 0;
}
However, in order to determine whether a character is an alphabetical letter, there is a much simpler solution: You can simply call the function isalpha as demonstrated in one of the other answers.
From scanf's man page:
RETURN VALUE:
On success, these functions return the number of input items successfully matched and assigned; this can be fewer than provided for, or even zero, in the event of an early matching failure.
According to this, the statement
if (scanf ("%c", &o) == a[i])
compares the return value of scanf, which in this case would be one 1(if scanf succeeded) to a[i], where i is uninitialised and leads to undefined behaviour. As I remember #Fe203 once saying:
"Leaving variables uninitialised is asking Demon of Hard-To-Find Bugs to co-author your code."
So you ought to first initialise i, then iterate through the array, comparing o to all the 54 values of i.
Aside:
You shouldn't be using scanf for user-interactive stuff. It is not supposed to be used as such, and it's quite hard to get right. In this case, consider using getc or getchar which reads one character at a time.
Or at least, check the return value of scanf.
This question already has answers here:
How should character arrays be used as strings?
(4 answers)
Closed 1 year ago.
I want to print out a 2d array of char that contains mips registers. I want to print each register separately. But my current code prints out all the registers together. Is there a better way to do this problem, such as using a double pointer array of chars?
My code so far:
char reg[][3] = {
{'$', 's', '0'},
{'$', 's', '1'},
{'$', 's', '2'},
{'$', 's', '3'},
{'$', 's', '4'},
{'$', 's', '5'},
{'$', 's', '6'},
};
int main(void){
for(int i = 0; i < sizeof(reg); i++)
{
printf("%s\n", reg[i]);
}
return 0;
}
My output:
$s0$s1$s2$s3$s4$s5$s6
$s1$s2$s3$s4$s5$s6
$s2$s3$s4$s5$s6
$s3$s4$s5$s6
$s4$s5$s6
$s5$s6
$s6
But I want my output to be like this:
$s0
$s1
$s2
$s3
$s4
$s5
$s6
First of all, it may be easier to treat the register names as strings, (i.e., char arrays terminated by a \0), especially since you are using %s to print out the string (the %s specifier expects a NUL terminated array of chars). So, you want the second dimension of the 2D reg array to be 4, in order to hold the \0:
char reg[][4] = {
{'$', 's', '0', '\0'},
{'$', 's', '1', '\0'},
{'$', 's', '2', '\0'},
{'$', 's', '3', '\0'},
{'$', 's', '4', '\0'},
{'$', 's', '5', '\0'},
{'$', 's', '6', '\0'}
};
Alternatively, you could write these out as strings directly:
char reg[][4] = {
"$s0",
"$s1",
"$s2",
"$s3",
"$s4",
"$s5",
"$s6"
};
Now onto the loop. The sizeof(reg) in the loop condition gives you the size (in bytes) of the 2D array reg which is 7*4 = 28.
What you really want to loop over is the number of rows in the 2D array. In your case, since the size of each register name is 4 (remember to include the NUL terminator!), you could do the following:
for(int i = 0; i < sizeof(reg)/4; i++)
{
printf("%s\n", reg[i]);
}
This is happening because in C, strings are null-terminated by convention. This means that printf called with the %s specifier will not stop until it reaches a null character.
To get your desired output without changing much of your code, you could add a null character at the end of each register like this
char reg[][4] = {
{'$', 's', '0', 0},
{'$', 's', '1', 0},
{'$', 's', '2', 0},
{'$', 's', '3', 0},
{'$', 's', '4', 0},
{'$', 's', '5', 0},
{'$', 's', '6', 0}
};
but that's not very pretty. You can write it like this:
char reg[][4] = {"$s0", "$s1", "$s2", "$s3", "$s4", "$s5", "$s6"};
These strings will be null terminated by default.
Another way to do this without changing your array will be to specify how many characters to print for each print call, something like this:
printf("%.3s\n", reg[i]);
Edit: As pointed out by ice05's answer, your loop condition is also false. This code might generate a segmentation fault. A common way to handle this case in C is to use a preprocessor macro, for example:
#define REGISTER_STRING_SIZE 3
char reg[][REGISTER_STRING_SIZE] = {
{'$', 's', '0'},
{'$', 's', '1'},
{'$', 's', '2'},
{'$', 's', '3'},
{'$', 's', '4'},
{'$', 's', '5'},
{'$', 's', '6'},
};
And then in your loop,
for(int i = 0; i < sizeof(reg)/REGISTER_STRING_SIZE; i++)
{
printf("%.3s\n", reg[i]);
}
This is not very elegant and I would recommend treating the registers as strings (adding the null terminator).
I have an inhomogenous 2 dimensional
char[][] array = {{'t', 'o', 'b', 'i', 'a', 's'},
{'h', 'e', 'i', 'n', 'd', 'e', 'l'},
{'1', '2', '1', '6', '3'}};
my return should be a String like this:
tobias heindel 12163
how should I do that?
You just have to create 2 loops that increase i from 0 to your array size and y from 0 to current array (its index represented by i) size where i is the current array and y is the char position at the current array.
I've been working to implement a base64 decoder in C. I have been reading up on base64 conversion in places such as the Wikipedia page and also using online converters to check my work. It seems straight forward: just replace every base64 character with the corresponding 6-bit binary string!
My Base64-to-binary decoding is correct as long as the base64 string to decode is a multiple of 4. If the string length is not a multiple of 4, or there are equal signs present for padding, my code does not match the results from online converters.
I thought I understood the padding -- just replace the '=' character with zeros (6, for 6 bits). However, I still don't match the converter's result when this is employed.
Here is the code I've written:
int main(void){
printf("Testing b642bin ...\n\n");
printf("Case 1: Converting 'AA==' to bin:\n");
printf("Expected Result: 000000000000000000000000\n");
printf("Actual Result: %s\n\n", b642bin("AA=="));
printf("Case 2: Converting '+aHg' to bin:\n");
printf("Expected Result: 111110011010000111100000\n");
printf("Actual Result: %s\n\n", b642bin("+aHg"));
printf("Case 3: Converting 'kNSHd94m7d+=' to bin:\n");
printf("Expected Result: 1001000011010100100001110111011111011110001001101110110111011111\n");
printf("Actual Result: %s\n\n", b642bin("kNSHd94m7d+="));
return 0;
}
char bin6_table[65][7] = {"000000", "000001", "000010", "000011", "000100",
"000101","000110", "000111", "001000", "001001",
"001010", "001011", "001100", "001101", "001110",
"001111", "010000", "010001", "010010", "010011",
"010100", "010101", "010110", "010111", "011000",
"011001", "011010", "011011", "011100", "011101",
"011110", "011111", "100000", "100001", "100010",
"100011", "100100", "100101", "100110", "100111",
"101000", "101001", "101010", "101011", "101100",
"101101", "101110", "101111", "110000", "110001",
"110010", "110011", "110100", "110101", "110110",
"110111", "111000", "111001", "111010", "111011",
"111100", "111101", "111110", "111111", "000000"};
char base64_table[65] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
'w', 'x', 'y', 'z', '0', '1', '2', '3',
'4', '5', '6', '7', '8', '9', '+', '/','='};
char* b64Char2bin(char b64){
int n = 64;
int k;
char *bin;
for(k=0;k<n;k++){
if (b64 == base64_table[k]) {
bin = bin6_table[k];
break;
}
}
return bin;
}
char* b642bin(char *b64_str) {
int i;
size_t len = strlen(b64_str);
char* bin_str = (char*)malloc(((len * 6) + 1) * sizeof(char));
for (i = 0; i < (int)len; i++) {
const char* binSextet = b64Char2bin(b64_str[i]);
memcpy(&bin_str[6*i], binSextet,7);
}
return bin_str;
}
The output looks like this:
Testing b642bin ...
Case 1: Converting 'AA==' to bin:
Expected Result: 000000000000000000000000
Actual Result: 000000000000000000000000
Case 2: Converting '+aHg' to bin:
Expected Result: 111110011010000111100000
Actual Result: 111110011010000111100000
Case 3: Converting 'kNSHd94m7d+=' to bin:
Expected Result: 1001000011010100100001110111011111011110001001101110110111011111
Actual Result: 100100001101010010000111011101111101111000100110111011011101111110000000
If the converter I provided is correct, I don't understand Base64. Clearly you do not simply replace each character with the corresponding 6 bits of binary. Why is Case 1 and 2 correct, but Case 3 is not?
Bytes (well, octets if you want to get all technical) are 8 bits long. Base64 encodes 6 bits at a time. Padding is used when the number of bytes that were encoded isn't a multiple of three, therefore the number of bits isn't a multiple of six. When decoding base64 with padding, you don't output more zero bits, you output less bits to produce the correct number of bytes.
As a concrete example:
Base64: ////
Binary: 11111111 11111111 11111111
Base64: //8=
Binary: 11111111 11111111
Base64: /w==
Binary: 11111111
So I have a sample code to create a deck of card for a mini poker game in c. But I do not understand how the suits and faces are determined. Why do these arrays have 2 dimensions? I know that [9] and [6] are the columns of the array, but I do not understand the purpose of them.
char suits[4][9]= {"Hearts","Diamonds","Clubs","Spades"};
char faces[13][6]= {"Ace","2","3","4","5","6","7","8","9", "10","Jack",
"Queen","King"};
The first set of square brackets is the number of elements in the first array, the second square bracket is the maximum length of the char array (string).
The second bracket in char suits[4][9] has nine spaces to allow space for the null character \0 which is used to terminate the string.
So the array actually looks like this:
char suits[4][9] = {
{'H', 'e', 'a', 'r', 't', 's', '\0'},
{'D', 'i', 'a', 'm', 'o', 'n', 'd', 's', '\0'},
{'C', 'l', 'u', 'b', 's', '\0'},
{'S', 'p', 'a', 'd', 'e', 's', '\0'}
};
When you have :
char suits[4][9]
it means that your array has 4 rows and the string that will be placed in each row can have a maximum length 9 and subtracting the ending '\0' character, maximum length 8.
Similarly,
char faces[13][6]
means that your array has 13 rows and the string that will be placed in each row can have a maximum length 6 and subtracting the ending '\0' character, maximum length 5.