Encoded normal plain text bmVv decoded to neo without any issues but this
AAAAgMom/1a/v0lblO2Ubrt60J2gcuXSljGFQXgcyZWveWLEwo6prwgi3iJIZdodyhKZQrNWp5nKJ3srRXcUW+F1BD3baEVGcmEgqaLZUNBjm057pKRI16kB0YppeGx5qIQ5QjKzsR8ETQbKLNWgRY0QRNVz34kMJR3P/LgHax/6rmf5AAAAAwEAAQ==
encoded string is not decoding. Just getting output buffer NULL/0.
This string decoded buffer should be single character. If I do that then I will get unsigned decode ASCII, but that ASCII code just viewable and writeable, can't use encoder to encode again that ASCII code because I am still getting buffer length of 0. It is because I used printf with %c to output buffer. It is not string to output using %s.
I need to output ASCII buffer as string. How is it possible to output ASCII buffer as string without using %c with printf/fwrite/scanf/putchar?
I expecting binary ASCII code as string to use again for encoding.
Expecting:
��&�V��I[��n�zН�r�Җ1�Axɕ�yb��"�"He���B�V���'{+Ew[�u=�hEFra ���P�c�N{��Hשъixly��9B2��M�,ՠE�D�s߉
%���k��g�
Here is base64 decode full code that I tried:
#include <stdio.h>
#include <stdlib.h>
char base64_map[64] = {
'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 *base64_decode(char *str)
{
int counts = 0;
char buffer[4];
char *plain = malloc(strlen(str) * 3 / 4 + 1);
int i = 0, p = 0;
for (i = 0; str[i] != '\0'; i++) {
int k;
for (k = 0; k < 64 && base64_map[k] != str[i]; k++);
buffer[counts++] = k;
if (counts == 4) {
plain[p++] = (buffer[0] << 2) + (buffer[1] >> 4);
if (buffer[2] != 64) {
plain[p++] = (buffer[1] << 4) + (buffer[2] >> 2);
}
if (buffer[3] != 64) {
plain[p++] = (buffer[2] << 6) + buffer[3];
}
counts = 0;
}
}
plain[p] = '\0';
return plain;
}
int main()
{
char *str = "AAAAgMom/1a/v0lblO2Ubrt60J2gcuXSljGFQXgcyZWveWLEwo6prwgi3iJIZdodyhKZQrNWp5nKJ3srRXcUW+F1BD3baEVGcmEgqaLZUNBjm057pKRI16kB0YppeGx5qIQ5QjKzsR8ETQbKLNWgRY0QRNVz34kMJR3P/LgHax/6rmf5AAAAAwEAAQ==";
printf("%s", base64_decode(str));
return 0;
}
If you're decoding binary data, as here, you can't print it using printf, because printf will stop at the first null byte.
To print binary data, you could have your base64_decode function return an explicit length, and then print that many characters. Perhaps something like this:
int main()
{
char *str = "…";
int len;
char *out = base64_decode(str, &len);
for(int i = 0; i < len; i++) putchar(out[i]);
return 0;
}
To make that work you would rewrite base64_decode's signature to
char *base64_decode(char *str, int *lenp)
and add the line
if(lenp != NULL) *lenp = p;
at the end, right before the return plain; statement.
Rather than the loop calling putchar, you could also use fwrite:
char *out = base64_decode(str, &len);
fwrite(out, 1, len, stdout);
And depending on what you're trying to do with the output, it would be easier to see (though perhaps not easier to process) if you output a hexadecimal representation of the bytes, rather than the bytes themselves:
for(int i = 0; i < len; i++)
printf("%02x", (unsigned char)out[i]);
Related
I need the length of an array. One way works perfectly, one gives the wrong answer, and one doesn't compile.
This doesn't compile:
size_t len = sizeof(array) / sizeof(array[0]);
This counts only first 4 letters:
size_t len = sizeof(array) / sizeof(char);
And len = 12 works.
I really don't understand this so some hint is greatly appreciated.
const char array[] = {'t', 'h', 'i', 's', 'i', 's', 'm', 'y', 't', 'e', 'x', 't', '\0'};
void count_chars(const char *array, unsigned int *counts)
{
size_t len = 12;
for(size_t i = 0; i < len; i++){
counts[(int)array[i]]++;
}
}
You cant determine the size of the passed array inside function. You need to pass size as an additional parameter.
const char array[] = {'t', 'h', 'i', 's', 'i', 's', 'm', 'y', 't', 'e', 'x', 't', 0};
void count_chars(const char *arr, unsigned int *counts, size_t size)
{
for(size_t i = 0; i < size; i++)
counts[(unsigned)arr[i]]++;
}
int main(void)
{
int cnt[sizeof(array[0]) * (1 << CHAR_BIT)];
count_chars(array, cnt, sizeof(array) / sizeof(array[0]));
}
You need to cast to unsigned (not int) because char values can be negative.
What you are trying to do is actually impossible in C. The general rule of thumb is to calculate the length of the array in the function where the array is declared and pass it to the function. This is due to the fact that C doesn't pass the entire array when calling a function but rather just the base address as a pointer variable. To breakdown your approaches and the reason they do/don't work are:
size_t len = sizeof(array) / sizeof(array[0]);
This the commonly accepted approach but the prerequisite is that array must be declared in the same scope not be a pointer.
size_t len = sizeof(array) / sizeof(char);
As array is pointer a type variable and therefore has the size 4(atleast on 32-bit machines) dividing by sizeof(char) is 1 resulting in the answer 4
size_t len = 12;
This works as it's hard coded.
An easy solution in your case could be use:
size_t len = strlen(array)
as mentioned assuming you can guarantee that the last element will be 0 or '\0'. In this situation you could also simply modify the looping condition to:
for(int i = 0; array[i] != 0; i++) {
...
}
Hope I could clarify your doubt
size_t len = sizeof(array) / sizeof(array[0]);
This is general approach for getting the length of an array. However, this will not work inside count_chars function because array is defined as local variable (a pointer) inside the API. And if it is the case, the result will be 13 (not 12 as you mentioned) because it count also the \0 at the end.
For string of characters, it is possible to use strlen. As in the question, you expected result = 12 so this might be your right solution. However, this will not work if there is some \0 value in the middle because it will find first string terminator (\0).
In C if you want to get length of Null Terminated Strings you have to check for NULL \0 and count characters.
Check here how strlen method works.
//Custom Strlen function.
size_t my_strlen(const char *str)
{
register const char *s;
for (s = str; *s; ++s);
return(s - str);
}
Strlen Source
To count length of Arrays (General) like Int,Float,Double you can use below method.
size_t int_arr_len = sizeof(int_arr) / sizeof(int_arr[0]);
size_t float_arr_len = sizeof(float_arr) / sizeof(float_arr[0]);
Full Source Code below
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
const char char_arr[] = {'t', 'h', 'i', 's', 'i', 's', 'm', 'y', 't', 'e', 'x', 't', 0}; // `\0` Null Terminated.
const int int_arr[] = {10, 20, 30, 40, 50};
const float float_arr[] = {1.5f, 2.5f, 3.5f, 4.5f, 5.5f};
//Custom Strlen function.
size_t my_strlen(const char *str)
{
register const char *s;
for (s = str; *s; ++s);
return(s - str);
}
int main()
{
//Array length for Strings(Char array. Null Terminated. `\0`)
size_t char_arr_len1 = strlen(char_arr);
size_t char_arr_len2 = my_strlen(char_arr);
//Array length for General arrays like Int,Float,Double...etc
size_t int_arr_len = sizeof(int_arr) / sizeof(int_arr[0]);
size_t float_arr_len = sizeof(float_arr) / sizeof(float_arr[0]);
//Print length of arrays.
printf("char_arr_len1: %zu\n", char_arr_len1);
printf("char_arr_len2: %zu\n", char_arr_len2);
printf("int_arr_len: %zu\n", int_arr_len);
printf("float_arr_len: %zu\n", float_arr_len);
return 0;
}
/*Using structures, write an interactive C program to
generate Grade Card for BCA first semester courses for
20 students of your study centre.*/
#include<stdio.h>
struct Marks
{
char subject[5];
float subject_marks[5];
};
struct GradeCard
{
char name[30];
int roll_num;
struct Marks table;
};
int main()
{
struct GradeCard student;
int i;
//name of student
printf("Enter the name of student: \t");
scanf("%s", &student.name);
//roll number of student
printf("Enter the roll number of student: \t");
scanf("%d", &student.roll_num);
//name of courses
printf("Enter the subjects: \t");
student.table.subject[5] = {'B', 'C', 'D', 'E', 'F'};
//marks in respective courses
for (i = 0; i < 5; i++)
{
scanf("%f", &student.table.subject_marks[i]);
}
//printing all the details
printf("%s\n", student.name);
printf("%d\n", student.roll_num);
for(i = 0; i < 5; i++)
{
printf("%s : %f\n",student.table.subject[i], student.table.subject_marks[i]);
}
}
I have to do this for 20 students. I want to try it with one student first. The error I am getting is this:
error: expected expression before '{' token
student.table.subject[5] = {'B', 'C', 'D', 'E', 'F'};
For this line:
student.table.subject[5] = {'B', 'C', 'D', 'E', 'F'};
I guess that OP thinks that the line assigns values to all the elements of the array student.table.subject[5] in the same way that char subject[5] = {'B', 'C', 'D', 'E', 'F'}; initializes all elements of the array subject[5]. They may look similar, but an assignment is not the same as an initialization.
There are some problems with the assignment attempted above. :-
Problem 1: {'B', 'C', 'D', 'E', 'F'} on the right side of an assignment expression is not a value of any type. It could be turned into a value of type char [5] by changing it into a compound literal. (char [5]){'B', 'C', 'D', 'E', 'F'} is a compound literal of type char [5]; it could also be written as (char []){'B', 'C', 'D', 'E', 'F'} where the number of elements is determined by the number of initializers between the braces. It is an unnamed array object.
Problem 2: In most expressions, a value of an array type is converted into a pointer to the first element of the array and is no longer an lvalue. The left hand operand of the assignment operator = must be an lvalue. Therefore, the left hand operand of the assignment operator cannot be an array.
There are various ways to solve OP's problem. :-
Solution 1: Use memcpy to copy the values from another array:
static const char subjects[5] = {'B', 'C', 'D', 'E', 'F'};
memcpy(student.table.subject, subjects, 5);
or:
memcpy(student.table.subject, (char [5]){'B', 'C', 'D', 'E', 'F'}, 5);
(Note: That makes use of a compound literal containing the source array contents to be copied to the destination.)
or:
memcpy(student.table.subject, "BCDEF", 5);
(Note: "BCDEF" is just being used for convenience there. It has type char [6] including the null terminator, but only the first 5 elements are being copied.)
Solution 2: Use a for loop to copy the values from another array:
static const char subjects[5] = {'B', 'C', 'D', 'E', 'F'};
for (i = 0; i < 5; i++)
{
student.table.subject[i] = subjects[i];
}
or:
for (i = 0; i < 5; i++)
{
student.table.subject[i] = ((char []){''B', 'C', 'D', 'E', 'F'})[i];
}
or:
for (i = 0; i < 5; i++)
{
student.table.subject[i] = "BCDEF"[i];
}
Solution 3: Assign to each element of the array using a linear sequence of statements:
student.table.subject[0] = 'B';
student.table.subject[1] = 'C';
student.table.subject[2] = 'D';
student.table.subject[3] = 'E';
student.table.subject[4] = 'F';
(Note: For a large number of elements, that would get tedious and be an inefficient use of executable memory unless the compiler can optimize it to the equivalent of a memcpy.)
With the following code, I'm trying to encode a string to a base 64. I couldn't figure out how to call the method.
I'm trying to convert the input string "test" to "dGVzdA==" in base64.
I've tried using strcpy(data,txt), but couldn't figure out how to complete the method call.
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdint.h>
#include <stdlib.h>
static char encoding_table[] = {'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', '+', '/'};
static int mod_table[] = {0, 2, 1};
char *base64_encode(char *data,
size_t input_length,
size_t *output_length) {
*output_length = 4 * ((input_length + 2) / 3);
char *encoded_data = malloc(*output_length);
if (encoded_data == NULL) return NULL;
for (int i = 0, j = 0; i < input_length;) {
uint32_t octet_a = i < input_length ? (unsigned char)data[i++] : 0;
uint32_t octet_b = i < input_length ? (unsigned char)data[i++] : 0;
uint32_t octet_c = i < input_length ? (unsigned char)data[i++] : 0;
uint32_t triple = (octet_a << 0x10) + (octet_b << 0x08) + octet_c;
encoded_data[j++] = encoding_table[(triple >> 3 * 6) & 0x3F];
encoded_data[j++] = encoding_table[(triple >> 2 * 6) & 0x3F];
encoded_data[j++] = encoding_table[(triple >> 1 * 6) & 0x3F];
encoded_data[j++] = encoding_table[(triple >> 0 * 6) & 0x3F];
}
for (int i = 0; i < mod_table[input_length % 3]; i++)
encoded_data[*output_length - 1 - i] = '=';
return encoded_data;
}
int main() {
char txt[] = "test";
char *data;
//... Please help
}
How can I convert txt ("test") to "dGVzdA==" and print it?
Here is a main() that calls base64_encode():
int main(void) {
char data[] = "test";
char *encoded_data;
size_t len;
encoded_data = base64_encode(data, strlen(data), &len);
printf("%s (%zu) => %s (%zu)", data, strlen(data), encoded_data, len);
}
Explanation
char data[] contains your string to encode. You'll need to pass it as an argument to base64_encode().
char *encoded_data is a pointer that you'll use to store the return value of base64_encode(). You will use this variable to access the decoded string, since base64_encode() returns a pointer to an allocated space where the decoded string is stored.
size_t len is a variable that will be used to store the size of the decoded string. You'll give a pointer to this variable as argument to base64_encode().
strlen(data), the second argument to base64_encode(), is the length of char data[].
You should read a book or tutorial about C programming as calling functions is a very basic concept.
To answer your question pass the plaintext, it's length, and the address of a variable to receive the resulting output's length:
int main() {
char txt[] = "test";
char *data;
size_t output_length;
data = base64_encode(txt, strlen(txt), &output_length);
printf("%*s\n", output_length, data);
}
The function returns a pointer to the data. In the code sample above that will be assigned to data. The length of the returned string will be set by the function in the output_length variable.
It's important to note that the returned string is not null terminated in base64_encode(). This can lead to problems later in your code if you were to assume that it is a null terminated string and tried to use it as such. For example naively printing it or trying to find its length with strlen() could result in a buffer overrun and possibly a program crash.
You could append a null character ('\0') to data, however, base64_encode() allocates only enough space for the encoded string so strictly speaking appending anything could access invalid memory causing a crash. Solutions to this include:
Treat the string with care. Print it with something like this:
printf("%*s", output_length, data);
Allocate your own string of length output_length + 1 , copy the
encoded string to the new string, then null terminate the new string:
data = base64_encode(txt, strlen(txt), &output_length);
char *encoded = malloc(output_length + 1);
strncpy(encoded, data, output_length);
encoded[output_length] = '\0';
Finally, be sure to call free(data) when you have finished with the base64 encoded data to ensure that the memory allocated in function base64_encode() is released.
#include<stdio.h>
#include<string.h>
int main()
{
int j;
char password[8] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'};
j = strlen(password);
printf("Size = %d\n", j);
return 0;
}
Outputs:
Size = 8
But this code
#include<stdio.h>
#include<string.h>
int main()
{
int j;
char password[8] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'};
char enteredpassword[9];
j = strlen(password);
printf("Size = %d\n", j);
return 0;
}
Outputs:
Size = 14
The difference between the two codes is that unused "enteredpassword[9]" array, is that supposed to change the string length of password[8] from 8 to 14?
strlen expects a null-terminated string. Your character array lacks null terminator
char password[] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', '\0'};
// ^^ ^^^^
j = strlen(password);
Calling strlen on a string that is not null-terminated is undefined behavior, meaning that your program could crash or return an unpredictable result. Note how the change removes the hard-coded length of the password array, letting the compiler figure out the correct size.
Your password is not a null-terminated string. If you initialize it conventionally:
char password[] = "abcdefgh";
or
const char *password = "abcdefgh";
then calling strlen on it will give you the expected answer.
(Or, if you're bound and determined to do it the hard way, use
char password[] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', '\0'};
or
char password[9] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', '\0'};
.)
Your program has invoked undefined behaviour , therefore , possible explanation is anything can appear as output (if lucky you get seg fault).
char password[8] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'}; //not a C-style string
password is not a null-terminated string and passing it to strlen will cause UB.
j = strlen(password); //will invoke UB
Either write -
char password[9] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h','\0'};
or
char password[]="abcdefgh";
The function strlen() is to be used with strings. In C strings are array of characters terminated by a \0. But your array is not NULL \0 terminated.
Try the following
char password[9] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', '\0'};
Your code has undefined behavior, since you're calling strlen() on arrays of characters that are not properly 0-terminated, i.e. they are not strings.
The normal way to initialize a string in C is something like that:
char mystr[100]="test string";
Because every string ends up with a NULL character ('\0'), so you must initialize your string like the following:
char password[8] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', '\0'};
In this case, your password string was null-terminated and the strlen() will return the correct answer.
I'm trying to delete characters in a string by replacing them with empty quotes. It's giving me the following error message:
incompatible pointer to integer conversion assigning to
'char' from 'char [1]' [-Wint-conversion]
source[i] = "";
^ ~~
I'm getting the same error when I replace the empty string with a character and I thought this was the procedure for replacing array elements, so I'm not sure how to proceed.
Here's my code:
#include <stdio.h>
#include <string.h>
int removeString(char source[], int startIndex, int numberRemove) {
int i;
for (i = startIndex; i < startIndex + numberRemove; i++) {
printf ("%c", source[i]);
source[i] = "";
}
for (i = 0; i < strlen(source); i++) {
printf("%c\n", source[i]);
}
return 0;
}
int main (void) {
char text[] = { 'T', 'h', 'e', ' ', 'w', 'r', 'o', 'n', 'g', ' ', 's', 'o', 'n' };
removeString(text, 4, 6);
return 0;
}
You cannot assign "" to a char! "" is a char * (It's better to say an ASCII0 string).
I think you want insert a 0 code in the string! This is not a good choice because 0 indicates the end of an ASCII0 string.
You may substitute the char with a space:
source[i] = ' ';
But I think it's not what you want!
To take off the char from the string you have to move all chars after the char you want remove on the char to be deleted. ;)
If you want that an ASCII0 string is printed and managed as a void string
just put a 0 in the first byte!!!
source[0]=0;
or
*source=0;
Try using:
memset(source, 0, strlen(source));
This will set the entire string length to null terminate char. What you are doing above:
source[i] = "";
is an error for several reasons:
When you set a char in C, you use single quotations: ''
empty and null terminate char are not the same.
Solved it. Basically I'm looping over the string and printing out the chars if they are within the specified value range.
#include <stdio.h>
#include <string.h>
int removeString(char source[], int startIndex, int numberRemove) {
int i;
for (i = 0; i < strlen(source); i++) {
if (i < startIndex || i >= startIndex + numberRemove) {
printf("%c", source[i]);
}
}
return 0;
}
int main (void) {
char text[] = { 'T', 'h', 'e', ' ', 'w', 'r', 'o', 'n', 'g', ' ', 's', 'o', 'n', '\0' };
removeString(text, 4, 6);
return 0;
}