Printing char array with null character in the middle in C - c

I have noticed that when you try to print a null character in C, nothing will get printed.
printf("trying to print null\n");
printf("%c", '\0');
However, I am trying to print the characters in the following array one by one, up to the sixth character which is the null character.
char s[] = "Hello\0Bye";
int i;
for(i = 0; i < 7; i++) {
printf("%c", s[i]);
}
printf("\n");
I was expecting "Hello" to be printed, as since the sixth character is null nothing will be printed. However my output was: "HelloB".
It seems like printf skipped the null character and just went to the next character. I am not sure why the output is "HelloB" instead of "Hello".
Any insights would be really appreciated.

The construction '\0' is commonly used to represent the null character. Here
printf("%c", '\0');
it prints nothing.
And in the decalaration of s
char s[] = "Hello\0Bye";
when you print like
for(i = 0; i < 7; i++) {
printf("%c", s[i]);
}
printf() prints upto 0<7(h), 1<7(e)..5<7(nothing on console),6<7(B) iterations only and 6th charactar is B hence its prints HelloB.
I was expecting "Hello" to be printed ? For that you should rotate loop until \0 encountered. For e.g
for(i = 0; s[i] != '\0'; i++) { /* rotate upto \0 not 7 or random no of times */
printf("%c", s[i]);
}
Or even you no need to check s[i] != '\0'
for(i = 0; s[i]; i++) { /* loop terminates automatically when \0 encounters */
printf("%c", s[i]);
}

You can use below two options
1. size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
2.Iterate through each character and print it.

int i; for(i=0; i<7; i++) generates 7, not 6 iterations.
Printing \0 generates no pixels on the console (character 6) and then the 7th character (B follows).

Related

Why is this code printing a random character inbetween the input and output lines?

I'm trying to write a program (in C) where the input is reversed and printed in reverse line by line. For the most part, the code actually does just that. The trouble is that for some (most) of my input, I will get a random character or an extra newline in between my input and my output in the console.
For example, I start the program, type "testing" into the console, and get "gnitseT" back after hitting enter. This has happened successfully and is what I expect. It looks like this:
Testing
gnitseT
But then when I type "Hello" into the console, it looks like this:
Hello
g (unexpected)
olleH
Or if I type "running" into the console, instead of getting an unexpected "g" in between my input and output lines, I get an extra newline.
Running
newline here
extra newline here (unexpected)
gninnuR
#include <stdio.h>
void reverse(int length, char s[])
{
int i;
for (i = length; i >= 0; i--)
{
printf("%c", s[i]);
}
printf("\n");
}
int main(void)
{
char smain[2000];
int c;
int i;
i = 0;
while ((c = getchar()) != EOF)
{
smain[i] = c;
i++;
if (c == '\n')
{
reverse(i, smain);
i = 0;
}
}
return 0;
}
The expected behavior is for the program to output into the console the reversed input after the enter key is pressed.
Sometimes, especially at the very beginning of the program, it will work perfectly.
Then, it starts giving me a random character in between my input and output, or it starts giving me an extra newline.
I would like to have it so that it just prints the input in reverse order without any unexpected odd characters showing up in between the input and the output.
Thanks for any help.
Your immediate problem is you are reading and attempting to print one character past the end of the characters stored in your array with
for (i = length; i >= 0; i--) {
printf("%c", s[i]);
}
Why? You add length characters to smain in main(). In C, arrays are zero-based. The characters in your string are from 0 -> length-1 (the nul-character in a string is located at s[length], but here you never add a nul-terminating character, so the value at that index is simply indeterminate). If the element has not been initialized (which it will not be on your first word or any subsequent word equal to or longer than your longest word entered at that time) Undefined Behavior results since you are attempting to read and print an indeterminate value from an uninitialized element in array. How your terminal will output the indeterminate is undefined -- and may well result in a G being printed.
To correct the problem, loop for (i = length - 1; i >= 0; i++) or very simply:
while (length--)
printf ("%c", s[length]);
putchar ('\n'); /* don't printf a single-character */
(note: don't call the variadic printf function to output a single-character, that is what putchar() is for)
Putting it altogether and fixing your logic so you don't add and print the '\n' as part of every word you are reversing, you could do:
#include <stdio.h>
#define MAXC 2048 /* if you need a constant, #define one (or more) */
void reverse(int length, char s[])
{
while (length--)
printf ("%c", s[length]);
putchar ('\n'); /* don't printf a single-character */
}
int main (void) {
char smain[MAXC];
int c, i = 0;
while ((c = getchar()) != EOF) {
if (c == '\n') {
reverse(i, smain);
i = 0;
}
else
smain[i++] = c;
}
if (i) /* protect against file with no POSIX end-of-file */
reverse (i, smain);
return 0;
}
(note: the if {...} else {...} logic to prevent adding the '\n')
Example Use/Output
$ printf "Hello\nGoodbye\n" | ./bin/prnrevlines
olleH
eybdooG
Which will work just as well without the POSIX eof, e.g.
$ printf "Hello\nGoodbye" | ./bin/prnrevlines
olleH
eybdooG
on line 29
++i;
this means "i" now have length+1 so, you have been out of the string, you can change the program to :
#include <stdio.h>
void reverse(int length, char s[])
{
int i;
for (i = length; i >= 0; i--)
{
printf("%c", s[i]);
}
printf("\n");
}
int main(void)
{
char smain[2000];
int c;
int i;
i = 0;
while ((c = getchar()) != EOF)
{
smain[i] = c;
if (c == '\n')
{
reverse(i, smain);
i = 0;
}
else i++;
}
return 0;
}

Why when my input is 8 or more characters long, symbols appear after printing the 8 character?

When I print 8 or more characters, symbols always print after the 8th character. Does anyone know what is wrong with the code and how can I fix this?
I've tried with different numbers of characters and it always happens when is more than 8 or 8.
#include <stdio.h>
int main() {
char ch = 0;
char temp[100];
int i = 0;
while (scanf("%c", &ch) == 1) {
if (ch != '\n') {
temp[i] = ch;
printf("%s", temp);
i++;
}
}
return 0;
}
My expected result is
1 12 123 123412345123456123456712345678
My actual output is
1 12 123 123412345123456123456712345678xxx
the x represent the symbols
The reason you get funny characters in the output is the temp array is not a proper C string because it is uninitialized so there is not necessarily a null byte '\0' after the ith entry set with temp[i] = ch;.
There are different ways to fix this problem:
you can initialize temp this way: char temp[100] = { 0 };
you can set the byte at temp[i+1] to '\0' in the loop.
Note also that the expected output is not 1 12 123 123412345123456123456712345678, but 112123123412345123456123456712345678 because you do not output a separator between the strings. It would be less confusing to output the strings on separate lines.
Finally scanf() will not return until the user has typed a newline because of buffering performed by the terminal driver and the standard input stream.
Here is a modified version:
#include <stdio.h>
int main() {
char ch;
char temp[100];
size_t i = 0;
while (scanf("%c", &ch) == 1 && i + 2 < sizeof(temp)) {
if (ch != '\n') {
temp[i] = ch;
temp[i + 1] = '\0';
printf("%s", temp);
i++;
}
}
return 0;
}
#chqrlie well explained and offered 2 alternatives.
3rd alternative: change format
printf("%s\n", temp) expects temp to be a string. In C, a string has a null character, else it is not a string.
Code failed to ensure a '\0' in temp[]. The result is undefined behavior (UB).
Code could use a precision to limit the number of characters printed with "%s".
// printf("%s", temp);
printf("%.*s", (int)i, temp);
"%.*s", (int)i, temp will print up to i characters or up to '\0' - which ever comes first. i is cast as (int) because printf expects an int for the precision given as an extra argument as specified by the .* before the s.
int main(void) {
char temp[100];
size_t i = 0;
while (i < sizeof temp && scanf("%c", &temp[i]) == 1 && temp[i] != '\n') {
i++;
}
printf("<%.*s>\n", (int)i, temp);
return 0;
}

How to calculate frequency of characters in a string [duplicate]

This question already has an answer here:
C program: how to find the maximum/minimum frequency of a character in a string
(1 answer)
Closed 6 years ago.
I am a beginner with C programming so my code is very basic. It is to count the frequency of characters in a string. The program does run but the problem is that it displays each character as many times as it appears in the string. So, when I enter hello, I get "h occurs 1 times, e occurs 1 times, l occurs 2 times, l occurs 2 times, o occurs 1 times". How do i eliminate this and make the count for l appear only once?
for(i=0;str[i]!='\0';i++)
{
for(j=0;str[j]!='\0';j++)
{
if(str[i]==str[j])
count[i]++;
}
}
for(i=0;i<str[i]!='\0';i++)
printf("%c occurs %d times \n",str[i],count[i]);
I think building your own function which removes duplicated characters would help you in achieving what you are trying to do. But, there is no standard function that would help you in removing all the duplicates from a string. So try constructing a function to remove all the duplicated/repeated characters from a string and returns the string. Here's what your function would look like:
char* remove_duplicated(char* str, int size) {
int frequency[256] = {0};
char* new_str = malloc(size);
int new_size = 0;
for(int i=0; str[i]!='\0'; i++)
{
if(frequency[(unsigned char) str[i]] == 0) {
frequency[(unsigned char) str[i]]++;
new_str[new_size] = str[i];
new_size++;
}
}
new_str[new_size] = '\0';
return new_str;
}
Once you have constructed the above function, send the string in which you want to have the frequencies of characters measured and store the returned string. Something like this:
char* new_str = remove_duplicated(str, size);
Now in the double for loop that you are using, use new_str for your outer for loop and also use it for the for loop displaying count
for(i=0; new_str[i]!='\0'; i++)
{
for(j=0; str[j]!='\0'; j++)
{
if(new_str[i] == str[j])
count[i]++;
}
}
for(i=0; new_str[i]!='\0'; i++)
printf("%c occurs %d times \n", new_str[i], count[i]);
don't forget to free the malloced array in the remove_duplicated function:
free(new_str);
Here's an online demo: https://ideone.com/KnkwGX
You can use something like
int characters[128] = {0};
char string[] = "Hello, World!";
for(int i = 0; string[i] != '\0'; i++)
characters[(int)string[i]]++;
for(int i = 0; i < 128; i++)
if(characters[i] != 0)
printf("%c occurs %d times\n", (char)i, characters[i]);
It is going to be a little difficult to print the count of each letter uniquely with the way you have coded. Try the following way:
int frequency[122] = {0}; //ascii value of z is 122.
for(i=0;str[i]!='\0';i++)
{
frequency[str[i]]++;
}
for(i=0;i<=122;i++) {
if(frequency[i] != 0)
printf("%c occurs %d times\n", str[i], count[i]);
}

Unwanted characters after word in output

I created a program that asks the user for a word and then it arranges the letters in that word in alphabetical order and stores it in another string.
#include <stdio.h>
main()
{
char in[100],out[100],ch;
int i,len,j=0;
//ask user for a word
printf("Enter a word: ");
scanf("%s",in);
//arrange that word in alphabetical order
for(ch = 'a'; ch <= 'z'; ++ch)
for(i = 0; i < strlen(in); ++i)
if(in[i] == ch)
{
out[j] = ch;
++j;
}
//print the word
printf("%s",out);
fflush(stdin);
getchar();
}
The problem is when word is stored in the other string, there are some extra letters or symbols after that word. Can someone please tell me what could be possibly wrong with my code?
You're not null terminating the output string. printf("%s",out); will keep outputting characters until it finds 0 ('\0'). There are many options to fix this:
terminate the output to the current iterator position after the for-loop:
out[j] = '\0';
make the output the same length as the input:
out[strlen(in)] = '\0';
declare a 0-initialized array:
char out[100] = { 0 };
fill the output array with zero's yourself:
memset(out, 0; sizeof(out));
...
As the sorting is concerned, if it's just for learning then it's fine, otherwise you should pick a more efficient sorting algorithm
C strings are null terminated
Use
out[j] ='\0';
before printf
The %s specifier searches for a null termination.
In your case it keeps on printing until it finds one, so you get some random symbols.
Also avoid use of fflush.
You might want to update your logic to sort uppercase characters too.
You might want to use a sort say bubble sort
l=strlen(in);
for(i = 0; i < l; i++)
{
for(j = i + 1; j < l - 1; j++)
if(in[j-1] > in[j]){
ch = in[j];
in[j] = in[j-1];
in[j-1] = ch;
}
}
printf("Sorted String :%s",in);

Comparing 2 Strings together and saving the results

#include <stdio.h>
#define MAX 1000
void any(char s1[], char s2[], char s3[]);
int main()
{
char string1[MAX], string2[MAX], string3[MAX];
printf("Jepni stringen 1\n");
scanf("%s", &string1); //saving string 1
printf("Jepni stringen 2\n");
scanf("%s", &string2); //saving string 2
any(string1, string2, string3); /*comparing characters from string 2 to string 1 and saving the places where they are equal on third string */
printf("%d", string3[0]); //printing the first character of the third string
return 0;
}
void any(char s1[], char s2[], char s3[])
{
int i, j, k;
k = 0;
for (j = 0; j != '\0'; j++) {
for (i = 0; i != '\0'; i++) {
if (s1[i] == s2[j]) {
s3[k] = i;
j++;
k++;
}
}
}
}
I am trying to create a c program that scans 2 strings (saves them on string 1 and 2) than the program using function any will see character by character if the string 2 characters are equal with the string 1,If they are it will give the first position where they are found.In case nothing is found it displays a -1.The program asks for the first character that is equal,thats why i am printing always the first character from string 3.The program isnt working cuz it always prints -1.
Example if i put on string 1 dad
and on string 2 the character d
dhe program should display the 0 position
if i put dad on string 1
and on string 2 i put a
it should display 1.
First of all the for loop doesn't begin because the condition is that j shall be different from zero.In ASCII '\0' is zero (maybe not on all machines), so you rather want to check that s2[j] is different from zero.Same for i.
Another thing is that s3 is an array of chars, so putting s3[k]=i doesn't make it equal to '1' or '2', but to 1 or 2 (ASCII values), so you should add 48 to i (good till '9', then you'll have two digits), or print the string character per character, with the %d format specifier:
void any(char s1[], char s2[], char s3[])
{
int i, j, k;
k = 0;
for (j = 0; s2[j] != '\0'; j++) {
for (i = 0; s1[i] != '\0'; i++) {
if (s1[i] == s2[j]) {
s3[k] = i;
j++;
k++;
}
}
}
}
Maybe I'm missing some other error, try the code and run it to see if it's right (also remember to use the %d specifier to print s3).

Resources