Random characters printed after printing 'result' - c

I'm getting random characters after the actual output in printf("%s",result);.
Why are these characters being printed? And how can I remove them?
#include<stdio.h>
char *replacechar(char[]);
int main()
{
char str[25];
char *result;
int i=0;
while( (str[i++]=getchar()) != '\n' && i < 25);
result= replacechar(str);
printf("%s",result);
return 0;
}
char *replacechar(char str[])
{
return str;
}
Expected Output:
aaayt
aaayt
Actual Output:
aaayt
aaayt
↑#

For starters the operands of the condition
(str[i++]=getchar()) != '\n' && i < 25
should be swapped.
i < 25 && (str[i++]=getchar()) != '\n'
The input stored in the character array str should be zero-terminated. Otherwise the array will not contain a string.
Here is a demonstrative program that shows how your code can be rewritten
#include <stdio.h>
char *replacechar( char str[] )
{
return str;
}
int main(void)
{
enum { N = 25 };
char str[N];
char *result;
size_t i = 0;
while( i < N - 1 && ( str[i] = getchar() ) != '\n' ) i++;
str[i] = '\0';
result = replacechar( str );
puts( result );
return 0;
}
Its output might look like
Hello Siddharth Awana
Hello Siddharth Awana

Related

How to write a function in c that counts words

I had an exam yesterday in which one of the questions was about counting words in a given string.
The definition of word would be a portion of a string that is divided by spaces and/or the beginning/end of the string
I am new to C, and was not able to create a condition where it increases the counter word when you find “space (characters) space”
int count_words(char *str)
int i = 0;
int word = 2;
while (str[i])
{
if (str[i] == ‘ ‘)
{
int l = 1;
while (str[i + l]
{
l++;
}
if (l != 1)
{
word++;
}
}
}
For starters the function should be declared like
size_t count_words(const char *str);
The function parameter should be declared with the qualifier const because the passed string is not being changed within the function and the function return type should be size_t that is the same return type as for example of standard string function strlen.
It is unclear why the variable word in your function is initialized by 2
int word = 2;
Or the variable i is not being changed within the function.
The function can look the following way as shown in the demonstration program below
#include <ctype.h>
#include <string.h>
#include <stdio.h>
size_t count_words( const char *s )
{
size_t n = 0;
while ( *s )
{
while ( isspace( ( unsigned char )*s ) ) ++s;
if ( *s )
{
++n;
while ( *s && !isspace( ( unsigned char )*s ) ) ++s;
}
}
return n;
}
int main( void )
{
const char *s = "How to write a function in c that counts words";
size_t n = count_words( s );
printf( "The string \"%s\"\ncontains %zu words\n", s, n );
}
The program output is
The string "How to write a function in c that counts words"
contains 10 words
If to use as delimiters only the space character ' ' then the header <ctype.h> should be removed and the function will look like
size_t count_words( const char *s )
{
size_t n = 0;
while ( *s )
{
while ( *s == ' ' ) ++s;
if ( *s )
{
++n;
while ( *s && *s != ' ' ) ++s;
}
}
return n;
}
A more general function that can process any delimiters can look the following way
size_t count_words( const char *s, const char *delim )
{
size_t n = 0;
while (*s)
{
s += strspn( s, delim );
if (*s)
{
++n;
s += strcspn( s, delim );
}
}
return n;
}
The function has a second parameter that specifies delimiters. For example the function can be called loke
size_t n = count_words( s, " \t?!:;,." );
Try this way:
# include<stdio.h>
# include<string.h>
# define MaxBufferSize 50
void main(){
int count =0, size;
char str[MaxBufferSize+2];
printf("Enter string(max char 50 only): ");
if(fgets(str,sizeof(str), stdin)) {
if(strlen(str) > MaxBufferSize) printf("Max chars exceeded so chars before the limit were used!!!\n");
str[strcspn(str, "\n")] = '\0';
}
size = strlen(str);
int i=0;
if(size == 0) printf("Nothing entered\n");
else {
while(i<size){
while(!isalnum(str[i]) && i<size) i++;// ignores all spaces and other chars
if(str[i] == '\0') break;
while(isalnum(str[i]) && i<size) i++;// includes all words and numbers
count++;
}
printf("Words in string: %d\n",count);
}
}
hope it helps...! ;)
#include <stdio.h>
int count_words(char *str) {
int i, count=0;
int in_word = 0; // Flag to track if we're currently inside a word or not
// Loop through each character in the string
for(i=0; str[i]!='\0'; i++) {
// If current character is not a space or newline and we're not already inside a word, increment word count
if((str[i]!=' ' && str[i]!='\n') && !in_word) {
count++;
in_word = 1; // Set flag to indicate we're currently inside a word
}
// If current character is a space or newline, set flag to indicate we're not inside a word
else if(str[i]==' ' || str[i]=='\n') {
in_word = 0;
}
}
return count;
}
#include <stdio.h>
#include <string.h>
void main()
{
char s[200];
int count = 0, i;
printf("Enter the string:\n");
scanf("%[^\n]s", s);
for (i = 0;s[i] != '\0';i++)
{
if (s[i] == ' ' && s[i+1] != ' ')
count++;
}
printf("Number of words in given string are: %d\n", count + 1);
}
Use this code it will definitely works fine ):

Reverse line function in C works unpredictably

I'm doing the exercises from C Programming Language, the one where you need to make a function to reverse a line. So I did and it works sometimes. But only some times. With the same test it gives different results. I really don't get it, and would appreciate some help. 3 tries out of 4 it would print around 150 spaces and 1 out of 4 it would print the reversed line just like I wanted, though with some junk in the end for some reason.
I was thinking of doing it with pointers, but couldn't figure them out as of now.
Here's my code:
#include <stdio.h>
void reverse(char theline[150]){
int i, j;
char tmp[150];
for (i = 0; theline[i] != 0; i++){
tmp[i] = theline[i];
}
for (j = 0; i >= 0; j++){
theline[j] = tmp[i];
i--;
}
}
int main() {
char line[150];
char c;
int counter = 0;
do {
counter = 0;
while (((c = getchar()) != '\n') && (c != EOF)) { //one line loop
line[counter] = c;
counter++;
}
if (counter > 80){
reverse(line);
printf("%s\n", line);
}
}
while (c != EOF);
return 0;
}
I compile it with "gcc -g -Wall program -o test" and the compiler doesn't give me any errors or warnings. My OS is Ubuntu and I test it with "./test < longtext.txt". This text file has a few lines of different length.
After this loop
while (((c = getchar()) != '\n') && (c != EOF)) { //one line loop
line[counter] = c;
counter++;
}
the character array line does not contain a string because the stored characters are not appended with the terminating zero character '\0'.
So this loop within the function
for (i = 0; theline[i] != 0; i++){
tmp[i] = theline[i];
}
invokes undefined behavior.
You need to append the array with the terminating zero character '\0'.
But even if the passed character array will containe a string the second for loop
for (i = 0; theline[i] != 0; i++){
tmp[i] = theline[i];
}
for (j = 0; i >= 0; j++){
theline[j] = tmp[i];
i--;
}
writes the terminating zero character '\0' in the first position if the array theline. As a result you will get an empty string.
Also the function shall not use the magic number 150 and an auxiliary array.
Pay attention to that the variable c should be declared as having the type int. In general the type char can behave either as the type signed char or unsigned char depending on compiler options. If it will behave as the type unsigned char then this condition
c != EOF
will always evaluate to true.
Without using standard C string functions the function can be declared and defined the following way
char * reverse( char theline[] )
{
size_t i = 0;
while ( theline[i] != '\0' ) i++;
size_t j = 0;
while ( j < i )
{
char c = theline[j];
theline[j++] = theline[--i];
theline[i] = c;
}
return theline;
}
Here is a demonstration program
#include <stdio.h>
char * reverse( char theline[] )
{
size_t i = 0;
while ( theline[i] != '\0' ) i++;
size_t j = 0;
while ( j < i )
{
char c = theline[j];
theline[j++] = theline[--i];
theline[i] = c;
}
return theline;
}
int main( void )
{
char s[] = "Hello World!";
puts( s );
puts( reverse( s ) );
}
The program output is
Hello World!
!dlroW olleH
Why muck-around with reversing a buffer when you can simply store-up the entered characters as they arrive.
#include <stdio.h>
int main() {
for( ;; ) {
char line[ 150 ];
int c, counter = sizeof line;
line[ --counter ] = '\0';
// NB: EOF is an int, not a char
while( ( c = getchar() ) != '\n' && c != EOF && counter > 0 )
line[ --counter ] = (char)c;
printf( "%s\n\n", line + counter );
counter = sizeof line;
}
return 0;
}
Output:
the quick
kciuq eht
Once upon a time in a land far awy
ywa raf dnal a ni emit a nopu ecnO
I wish I was what I was when I wished I was what I am now.
.won ma I tahw saw I dehsiw I nehw saw I tahw saw I hsiw I

what does my reversed array add random characters in C

I wrote code to reverse an array after in C.
I'm using C17. In the code the user is asked to input a word, the word then is put into an array
and then reversed.
The code works for the exception that it adds some random characters and I couldn't figure out why it does that.
Can you help me with that?
Here is my code
#include <stdio.h>
#define MAXLINE 80
void inputtoarray(char input[]); //Take the input from user and put it into an array
void reverseinput(char input1[]);
int main(){
char input[MAXLINE];
inputtoarray(input);
reverseinput(input);
return 0;
}
void inputtoarray(char input[]){
int c; //to hold the indiviual characters before going into the array
//int was used over char because I want to be able to hold EOF
int i; //i is the array counter
//ask the user to type in a word
printf("Please type in a word:\n");
for(i=0; (c=getchar()) != '\n'; ++i){
input[i] = c;
}
}
void reverseinput(char input1[]){
int cinput;
int coutput;
char temp[MAXLINE]; //define a temporary array
//count the number of characters in the array
for (cinput=0; input1[cinput] != '\0'; ++cinput){
}
coutput=cinput;
//the reversing process. Here cinput holds the number of the last character
for (cinput=0; coutput > 0; --coutput, ++cinput ){
temp[coutput] = input1[cinput];
//input1[coutput] = temp[coutput];
//printf("%s", temp);
}
input1 = temp;
printf("%s", input1);
}
The function inputtoarray does not input a string. As a result this loop
for (cinput=0; input1[cinput] != '\0'; ++cinput){
}
within the function reverseinput results in undefined behavior.
The function inputtoarray can look for example the following way
void inputtoarray( char input[], size_t n )
{
int c; //to hold the indiviual characters before going into the array
//int was used over char because I want to be able to hold EOF
size_t i = 0; //i is the array counter
//ask the user to type in a word
printf("Please type in a word:\n");
for ( ; i + 1 < n && ( c = getchar() ) != EOF && c != '\n'; ++i )
{
input[i] = c;
}
input[i] = '\0';
}
and called like
inputtoarray( input, MAXLINE );
Moreover this loop
for (cinput=0; coutput > 0; --coutput, ++cinput ){
temp[coutput] = input1[cinput];
//input1[coutput] = temp[coutput];
//printf("%s", temp);
}
does not set the element temp[0] due to the condition coutput > 0. So the first element of the array temp has an indeterminate value.
And this assignment
input1 = temp;
does not make a sense because it changes the local variable input instead of changing the array pointed to by the pointer (parameter) input.
Without using standard string functions the program can look the following way.
#include <stdio.h>
#define MAXLINE 80
void inputtoarray( char input[], size_t n )
{
int c; //to hold the indiviual characters before going into the array
//int was used over char because I want to be able to hold EOF
size_t i = 0; //i is the array counter
//ask the user to type in a word
printf("Please type in a word:\n");
for ( ; i + 1 < n && ( c = getchar() ) != EOF && c != '\n'; ++i )
{
input[i] = c;
}
input[i] = '\0';
}
void reverseinput( char input[] )
{
size_t n = 0;
while ( input[n] ) ++n;
if ( n != 0 )
{
for ( size_t i = 0; i < --n; i++ )
{
char c = input[i];
input[i] = input[n];
input[n] = c;
}
}
}
int main(void)
{
char input[MAXLINE];
inputtoarray( input, MAXLINE );
reverseinput( input );
puts( input );
return 0;
}
Its output might look like
Please type in a word:
Hello
olleH

Why is string modified in C even when I'm not trying to modify it?

I'm trying to solve exercise 1-19 in K&R C second edition. "Write a function reverse that reverses the character string s. Use it to write program that reverses its input a line at a time."
My solution takes two input strings s and t. s is source and t is target. And it copies the data in source s to t. I'm able to solve the problem, but I'm struggling hard to understand why would source string s be modified, even though it is not on the left hand side of the equal operator.
#include <stdio.h>
/* Solution to Exercise 1-19. Chapter 1 */
#define MAXLENGTH 10
int getln(char s[], int lim);
void reverse(char s[], char t[]);
int main()
{
int i, len;
char s[MAXLENGTH]; /* original string */
char t[MAXLENGTH]; /* reversed string */
while ((len = getln(s, MAXLENGTH)) > 0) {
printf("before reverse: %s", s);
reverse(s,t);
printf("reversed string: %s\n", t);
printf("after reverse: %s", s);
}
return 0;
}
/* getln: read a line into s, return length */
int getln(char s[], int lim)
{
int c, i, l;
l = 0;
for (i = 0; ((c = getchar()) != EOF) && (c != '\n'); ++i) {
if (i < (lim - 1)) {
s[l] = c;
++l;
}
}
if (c == '\n') {
s[l] = c;
++l;
}
s[l] = '\0';
return l;
}
/* reverse: reverses s to target t */
void reverse(char s[], char t[])
{
int i, j;
for (i = 0; s[i] != '\0'; ++i)
;
--i;
if (s[i] == '\n') {
--i;
}
for (j = 0; i >= 0; ++j) {
t[j] = s[i];
--i;
}
t[j] = '\0';
}
Test case:
$ ./a.out < testdata
before reverse: abcdefghi
reversed string: ihgfedcba
after reverse: abcdefghi
ihgfedcba$
Contents of file testdata:
$ cat testdata
abcdefghijklmnopqrstuvwxyz
$
There is a bug in the function getln To simplify the analyze of the function let's assume that lim is equal to 2.
Then in this loop
l = 0;
for (i = 0; ((c = getchar()) != EOF) && (c != '\n'); ++i) {
if (i < (lim - 1)) {
s[l] = c;
++l;
}
}
you can write lim-1 characters that is only one character. The loop stops its iterations when the user will press the key Enter that sends to the input buffer the new line character '\n'.
So the last read character is the new line character '\n'. This character is stored in the string after the loop
if (c == '\n') {
s[l] = c;
++l;
}
Now the limit is exhausted. Two characters of the passed character array are set.
However in the next statement
s[l] = '\0';
there is access to the memory beyond the limit when l is equal to 2.
That is all. The function invokes undefined behavior provided that the value of the parameter lim is equal to the size of the passed character array. The terminating zero character '\0' is written in the memory outside the character array and later can be overwritten.
I would define the function the following way as it is shown in the demonstrative program below.
#include <stdio.h>
size_t getln( char s[], size_t n )
{
size_t i = 0;
if ( n )
{
int c;
while ( i + 1 < n && ( c = getchar() ) != EOF && c != '\n' )
{
s[i++] = c;
}
if ( c == '\n' && i + 1 < n ) s[i++] = c;
s[i] = '\0';
}
return i;
}
int main(void)
{
enum { N = 10 };
char s[N];
while ( getln( s, N ) ) printf( "\"%s\"\n", s );
return 0;
}
If to enter
abcdefghijklmnopqrstuvwxyz
then the program output will be
"abcdefghi"
"jklmnopqr"
"stuvwxyz
"
That is only the last entered string contains the new line characters.
Pay attention to that in the exercise there is written
Write a function reverse that reverses the character string s.
This means that you need to reverse the original string itself instead of coping it in the reverse order to another character array.
Such a function can look the following way
#include <stdio.h>
char * reverse( char *s )
{
size_t n = 0;
while ( s[n] != '\0' ) n++;
if ( n && s[n-1] == '\n' ) --n;
for ( size_t i = 0; i < n / 2; i++ )
{
char c = s[i];
s[i] = s[n-i-1];
s[n-i-1] = c;
}
return s;
}
size_t getln( char s[], size_t n )
{
size_t i = 0;
if ( n )
{
int c;
while ( i + 1 < n && ( c = getchar() ) != EOF && c != '\n' )
{
s[i++] = c;
}
if ( c == '\n' && i + 1 < n ) s[i++] = c;
s[i] = '\0';
}
return i;
}
int main(void)
{
enum { N = 10 };
char s[N];
while ( getln( s, N ) ) printf( "\"%s\"\n", reverse( s ) );
return 0;
}
Again if the input is
abcdefghijklmnopqrstuvwxyz
then the program output is
"ihgfedcba"
"rqponmlkj"
"zyxwvuts
"
If you want to remove the new line character '\n' from the string inside the function reverse then substitute this statement
if ( n && s[n-1] == '\n' ) --n;
for this one
if ( n && s[n-1] == '\n' ) s[--n] = '\0';
You are not allocating memory for c or t, therefore you are overwriting things.

Why is my program to reverse its input a line at a time not working?

I was trying to write a program that reverses its input a line at a time. I thought I had done it successfully, however it sometimes doesn't give the desirable output (this happens when I put an input with a smaller length than the one I put previously). I am new to this and I was wondering what can I do to solve this issue.
Program:
#include <stdio.h>
#define MAXLINE 1000
void reverse(char o[], char l[]);
int mgetline(char line[]);
int main(void){
int len;
char line[MAXLINE];
char rev[MAXLINE];
while((len = mgetline(line)) > 0){
reverse(rev, line);
printf("%s\n",rev);
}
return 0;
}
int mgetline(char s[])
{
int c,i;
for(i = 0; ((c=getchar())!=EOF) && (c!='\n'); ++i)
s[i] = c;
if (c == '\n')
{
s[i] = c;
++i;
}
s[i] = '\0';
return i;
}
void reverse(char revi[], char liner[])
{
int i, c, j;
for(i=0;liner[i]!='\0';++i)
;
--i;
if(liner[i]=='\n')
--i;
for(j=0; j<=i ; ++j){
c = i - j;
revi[j] = liner[c];
}
--j;
}
Since you not terminating the revi string at the end, therefore it will print the leftout characters from the previous result if the new input is smaller. Fix it by adding this
revi[j] = '\0';
at the end of the reverse function and delete that last --j;.
The function reverse does not build a string that is it does not append the terminating zero '\0' to the result string.
The second parameter of the function should have the qualifier const because it is not changed in the function.
As all standard C string functions this function should return pointer to the result string.
And it is better to name the function like reverse_copy instead of reverse because the name reverse is usually used when a container is reversed "in place".
It can look the following way
char * reverse_copy( char revi[], const char liner[] )
{
size_t n = 0;
while ( liner[n] ) ++n;
if ( n != 0 && liner[n-1] == '\n' ) --n;
size_t i = 0;
while ( n != 0 ) revi[i++] = liner[--n];
revi[i] = '\0';
return revi;
}

Resources