C programming strange output, what did I do wrong? - c

#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.

Related

How to output plain ascii from base64 decode?

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]);

I am getting this error, "error: expected expression before '{' token". I don't know why ? syntax looks fine to me

/*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.)

C - Trouble calling a function

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.

Trying to delete string characters

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

How to get char array size in this case?

I'm with this doubt: how to get the size of a char array in this case:
#include<stdio.h>
void f(char * x)
{
printf("Size %d\n", sizeof(x)/sizeof(char));
}
main()
{
char x[5] = {'a', 'e', 'i', 'o', 'u'};
f(&x[0]);
}
Contrary to my expectations, I'm receiving 8 rather than 5 or even 6. What is wrong here?
Thanks!
sizeof(x) in your code will return the size of pointer char *x and not the size of the char array that x is pointing on
and the size of pointer in your 64-bits system is 8. and for 32-bits system the size of pointer is 4
Here, sizeof() is returning the size of the pointer, not the size of the original array.
The only way for f() to know the size of the array pointed to by the char* is for it to be told by the caller:
void f(char * x, size_t size)
{
...
}
main()
{
char x[5] = {'a', 'e', 'i', 'o', 'u'};
f(x, sizeof(x) / sizeof(x[0]));
}
You can not. sizeof returns the size of a pointer.
Store the size of your array in a variable and pass it too.
I prefer this:
void f(char *x, int size)
{
// ...
}
main()
{
char x[5] = {'a', 'e', 'i', 'o', 'u'};
f(x, 5);
}
sizeof(x) gives you size of the char pointer not the size of the array. char * is a pointer to a char. If you dochar a = 'A'; f(&a); it is still valid. char * is not designed to point to only char arrays, so sizeof(x) returns size of the pointer and not what it is pointing at.
You get it like this
void f(char * x, int size_of_array)
{
printf("Size %d\n", size_of_array);
}
main()
{
char x[5] = {'a', 'e', 'i', 'o', 'u'};
f(&x[0], 5);
}
Once you pass an array it decays into a pointer of that type, and you loose the ability to get the size of the array via the sizeof macro. You need to pass the number of elements. If your array is of numeric type you can always pass the size of an array as the first element:
void f(char * x)
{
printf("Size %d\n", x[0]);
}
main()
{
char x[6] = {6, 'a', 'e', 'i', 'o', 'u'};
f(&x[0]);
}
But of course in this case there's extra overhead to updating that element to make sure it matches what you expect.

Resources