int stringXor(char *str1,char *str2)
{
int num1=0,num2=0;
for (int i = 0; i<strlen(str1); i++)
{
num1=str1[i]-'0';
num2=str2[i]-'0';
num1 = num1 | num2;
str1[i]=(char)num1;
//printf("%d",str1[i]);
}
int count=0;
for(int j=0;j<strlen(str1);j++)
{
if(str1[j]==1)
count++;
}
return count;
}
I don't know what the error is, but or operation is not successful on each char of the string.
If you want a function that will return the number of positions that contain a 1 in either string, consider writing a simpler function that does just that. For example:
int CountOnes( char *str1, char *str2 )
{
int count = 0;
int len = strlen( str1 ); // we assume that strlen(str1) == strlen(str2)
for ( int i = 0; i < len; i++ )
{
if ( str1[ i ] == '1' || str2[ i ] == '1' )
count++;
}
return count;
}
Note that this function will not include the side effect of changing str1 as yours currently does.
To store the resulting OR'd string to str1, change the line
if ( str1[ i ] == '1' || str2[ i ] == '1' )
to
str1[ i ] = ( ( str1[ i ] - '0' ) | ( str2[ i ] - '0' ) ) + '0';
if ( str1[ i ] == '1' )
count++;
Related
The problem is simple: take a string, and reverse the position of ONLY letters (lower or uppercase). Leave any special characters where they are. My solution:
char * reverseOnlyLetters(char * S){
int Len = strlen(S);
char *StrBeg, *StrEnd, tempCh;
bool FoundStart = 0, FoundEnd = 0;
StrBeg = S;
StrEnd = S + (Len - 1);
for (int i = 0; i < (Len/2); i++)
{
if (((*StrBeg>= 'A') && (*StrBeg <= 'Z')) || ((*StrBeg >= 'a') && (*StrBeg <= 'z')))
{
FoundStart = 1;
}
else
{
StrBeg++;
}
if (((*StrEnd >= 'A') && (*StrEnd <= 'Z')) || ((*StrEnd >= 'a') && (*StrEnd <= 'z')))
{
FoundEnd = 1;
}
else
{
StrEnd--;
}
if(FoundStart && FoundEnd)
{
tempCh = *StrEnd;
*StrEnd = *StrBeg;
*StrBeg = tempCh;
StrBeg++;
StrEnd--;
FoundStart = 0;
FoundEnd = 0;
}
}
return S;
}
The issue is a testcase like "a-bC-dEf-ghIj" fails; the "E" and the "f" in the middle either don't get swapped at all, or (as I suspect), get swapped, but then get swapped BACK. Anyone see what I'm doing wrong?
Problem is this for (int i = 0; i < (Len/2); i++).
If lenght of string is even, it's ok, but in case it's even it doesn't go through the middle character. E in this "a-bC-dEf-ghIj" case, so it can't switch it with f.
The approach using this for loop
for (int i = 0; i < (Len/2); i++)
is incorrect. Let's assume that the string is "#AB". The result string will look like "#BA"
But using your loop you will have (as Len / 2 is equal to 1)
for (int i = 0; i < 1; i++)
In the first and single iteration of the loop the pointer StrBeg will be incremented
StrBeg++;
because the pointed character is not a letter.
So nothing will be reversed.
The function can be written simpler the following way
#include <stdio.h>
#include <string.h>
#include <ctype.h>
char * reverse_letters( char *s )
{
for ( char *first = s, *last = s + strlen( s ); first < last; ++first )
{
while ( first != last && !isalpha( ( unsigned char )*first ) ) ++first;
while ( last != first && !isalpha( ( unsigned char )*--last ) );
if ( first != last )
{
char c = *first;
*first = *last;
*last = c;
}
}
return s;
}
int main( void )
{
char s[] = "one, two, three";
puts( s );
puts( reverse_letters( s ) );
char s1[] = "#AB";
puts( s1 );
puts( reverse_letters( s1 ) );
}
The program output is
one, two, three
eer, hto, wteno
#AB
#BA
int main() {
int count[26]={0};
char input;
int i;
while(1){
scanf("%c", &input);
if(input>='a'&&input<='z') count[input-'a']++;
else if(input>='A'&&input<='Z') count[input-'A']++;
else break;
}
for (i=0; i<26; i++) {
if(count[i]!=0) {
printf("%c : %d\n", 'A'+i, count[i]);
}
}
return 0;
}
I want this code to stop when a value other than A~Z or a~z is entered.
How should I fix this code?
Here is a demonstrative program that shows how the while loop can look. I considered the space character ' ' as a valid character but it is not counted.
#include <stdio.h>
#include <ctype.h>
int main(void)
{
unsigned int count['Z' - 'A' + 1] = { 0 };
const size_t N = sizeof( count ) / sizeof( *count );
char c;
while ( scanf( "%c", &c ) == 1 &&
( ( 'A' <= ( c = toupper(( unsigned char ) c ) ) && c <= 'Z' ) || c == ' ' ) )
{
if ( c != ' ' ) ++count[c - 'A'];
}
for ( size_t i = 0; i < N; i++ )
{
if ( count[i] )
{
printf( "'%c' : %u\n", ( char )( 'A' + i ), count[i] );
}
}
return 0;
}
If to enter this sentence
Hello World
then the program output will be
'D' : 1
'E' : 1
'H' : 1
'L' : 3
'O' : 2
'R' : 1
'W' : 1
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
I wonder how can i make this. I don't want any iteration or isalpha() and toupper() functions. We want to use our own code to read input. We assume that user enters all characters lowercase. This is what i've tried so far:
define MAX_LENGTH 100
int read_line(char str[],int);
void capitalize(char[]);
int main (void){
char A[MAX_LENGTH];
printf("Enter a text \n");
read_line(A, MAX_LENGTH);
capitalize(A);
puts(A);
}
int read_line(char str[],int n){
int ch,i=0;
while ((ch = getchar()) != '\n'){
if(i<MAX_LENGTH)
str[i++] = ch;
}
str[i] = '\0';
return i;
}
void capitalize(char str[]){
int x = strlen(str);
static int i = 0;
if(str[i]=='\0')
return;
if(str[i-1]==' '|| i == 0)
str[i] -= 32;
i++;
return capitalize(&str[i]);
}
Output is like this:
Enter a text:
asdf sdf df
Asdf sdf df
What is wrong with my code?
You code is invalid. For example even the function read_line
int read_line(char str[],int n){
int ch,i=0;
while ((ch = getchar()) != '\n'){
if(i<MAX_LENGTH)
str[i++] = ch;
}
str[i] = '\0';
return i;
}
is incorrect at least because when i is equal to MAX_LENGTH -1 there is an access memory beyond the character array
str[i] = '\0';
That is the condition of the loop is initially written incorrectly.
As for the recursive function then it can look for example the following way.
#include <stdio.h>
int is_blank( char c )
{
return c == ' ' || c == '\t';
}
char * capitalize( char *s )
{
if ( *s )
{
int blank = is_blank( *s );
if ( !blank )
{
*s &= ~' ';
}
capitalize( s + 1 );
if ( !blank && !is_blank( *( s + 1 ) ) && *( s + 1 ) )
{
*( s + 1 ) |= ' ';
}
}
return s;
}
int main(void)
{
char s[] = "hello everybody. how do you do?";
puts( s );
puts( capitalize( s ) );
return 0;
}
The program output is
hello everybody. how do you do?
Hello Everybody. How Do You Do?
Here is a similar demonstrative program but with your fixed function read_line.
#include <stdio.h>
#define MAX_LENGTH 100
int is_blank( char c )
{
return c == ' ' || c == '\t';
}
char * capitalize( char *s )
{
if ( *s )
{
int blank = is_blank( *s );
if ( !blank )
{
*s &= ~' ';
}
capitalize( s + 1 );
if ( !blank && !is_blank( *( s + 1 ) ) && *( s + 1 ) )
{
*( s + 1 ) |= ' ';
}
}
return s;
}
size_t read_line( char *s, size_t n )
{
int ch;
size_t i = 0;
while ( i + 1 < n && ( ch = getchar() ) != EOF && ch != '\n' )
{
s[i++] = ch;
}
s[i] = '\0';
return i;
}
int main(void)
{
char s[MAX_LENGTH];
read_line( s, MAX_LENGTH );
puts( s );
puts( capitalize( s ) );
return 0;
}
If to enter the string
hello everybody. how do you do?
then the program output will be the same as shown above.
hello everybody. how do you do?
Hello Everybody. How Do You Do?
If the bit-wise operations is unclear for you then you can substitute this statement
for this statement
*s &= ~' ';
for this statement
*s -= 'a' - 'A';
and this statement
*( s + 1 ) |= ' ';
for this statement
*( s + 1 ) += 'a' - 'A';
If to use your approach to the implementation of a recursive function with a static variable then it will be interesting to you why your function does not work will not be?
Let's consider it ignoring the first statement with the call of strlen.
void capitalize(char str[]){
int x = strlen(str);
static int i = 0;
if(str[i]=='\0')
return;
if(str[i-1]==' '|| i == 0)
str[i] -= 32;
i++;
return capitalize(&str[i]);
}
First of all after the first call the function for one string you may not call it a second time for another string because the static variable i will not be already equal to 0.
The condition of the if statement should be written at least like
if ( i == 0 || str[i-1]==' ' )
that is the order of sub-expressions shall be changed.
The return statement shall not contain an expression
return capitalize(&str[i]);
you could just write
capitalize(&str[i]);
Nevertheless the initial value of the pointer str was changed. However within the function you are using the index i relative the initial value of str of the first call of the function.
And I am sure it is interesting to you how correctly to rewrite the function, is not it?
The function can look the following way as it is shown in the demonstrative program below.
#include <stdio.h>
#define MAX_LENGTH 100
int is_blank( char c )
{
return c == ' ' || c == '\t';
}
char * capitalize( char *s )
{
static size_t i = 0;
if ( *( s + i ) )
{
if ( !is_blank( s[i] ) && ( i == 0 || is_blank( s[i-1] ) ) )
{
s[i] -= 'a' - 'A';
}
++i;
capitalize( s );
--i;
}
return s;
}
size_t read_line( char *s, size_t n )
{
int ch;
size_t i = 0;
while ( i + 1 < n && ( ch = getchar() ) != EOF && ch != '\n' )
{
s[i++] = ch;
}
s[i] = '\0';
return i;
}
int main(void)
{
char s[MAX_LENGTH];
read_line( s, MAX_LENGTH );
puts( s );
puts( capitalize( s ) );
return 0;
}
I would write the following:
void capitalize(char* str) {
if (! *str) return; // job done
*str = toupper(*str); // capitalize "correctly"
capitalize(++str);
}
the main problem is that you're using index and recursion at the same time, simple recursive solution would be:
void capitalize(char* str, bool start){
if (!*str) return; // end as soon as \0 is met
if (start)
if (*str >= 'a' && *str <= 'z') *str = (*str - 'a') + 'A'; // capitalize latin letters
capitalize(str + 1, *str == ' '); // work with next symbol
}
should be called as capitalize(str, true)
Should do the job:
void capitalize(char *s)
{
while(1) {
while (*s==' ') s++; // skip spaces
if (!*s) return; // check for end
if ('a'<=*s && *s<='z') *s -= 32; // capitalize if needed
while (*s && *s!=' ') s++; // advance
} // loop
}
(I call this "Stupid Character Processing")
I have data file in which some data is kept.
example: welcome user HII if while
I have made 2D character array to store all the keywords in c.
now I want two know if the data file contain the keyword or not.
enter code here
for(i=0;i<32;i++)
for(j=0;j<no_of_words_in_file;j++)
if(k[i]==t[j])
printf("%s is keyword",t[j]);
here the k[i] represents the 2D character array where all the keywords in c are stored and t[i] represents the 2D character array where all the words of file are stored.
I want to compare these 2D arrays without using strcmp.
To compare two strings without using standard C functions you can use a loop like that
#include <stdio.h>
int main(void)
{
char key[] = "while";
char word1[] = "while";
char word2[] = "when";
size_t i = 0;
while ( key[i] != '\0' && key[i] == word1[i] ) ++i;
int equal = key[i] == word1[i];
printf( "key == word1: = %d\n", equal );
i = 0;
while ( key[i] != '\0' && key[i] == word2[i] ) ++i;
equal = key[i] == word2[i];
printf( "key == word2: = %d\n", equal );
return 0;
}
The program output is
key == word1: = 1
key == word2: = 0
Or you can write a separate function. For example
#include <stdio.h>
int equal( const char *s1, const char *s2 )
{
while ( *s1 != '\0' && *s1 == *s2 )
{
++s1; ++s2;
}
return *s1 == *s2;
}
int main(void)
{
enum { N = 10 };
char key[][N] ={ "if", "while" };
const size_t N1 = sizeof( key ) / sizeof( *key );
char words[][N] = { "welcome", "user", "HII", "if", "while" };
const size_t N2 = sizeof( words ) / sizeof( *words );
for ( size_t i = 0; i < N2; i++ )
{
for ( size_t j = 0; j < N1; j++ )
{
if ( equal( key[j], words[i] ) )
{
printf( "\"%s\" == \"%s\"[%zu]\n", key[j], words[i], i );
}
}
}
return 0;
}
the program output is
"if" == "if"[3]
"while" == "while"[4]
I have a code like this:
char* s[4][10] = { "abc\0", "aab\0", "cbb\0" };
a want to type a character, like.. 'a', and iterate through the array of strings, check on each string if there's 'a' on it, and then count how many there's on it..
In this case, what I wanted to get is "abc" : 1, "aab" : 2, "cbb" : 0 ...
how can I do the loops to get this result?
char input = '\0';
scanf("%c", &input);
int i, j;
for(i=0; i<4; i++)
{
int count = 0;
for(j=0;j<10;j++)
{
if(s[i][j] == input) count++;
}
printf("%s : %d", s[i], count);
}
although please note, that simply copying and pasting will not teach you anything.
Here is a demonstrative program that shows how you can deal with different declarations of arrays
#include <stdio.h>
int main(void)
{
char* s[4][10] = { { "abc", "aab", "cbb" } };
for ( int i = 0; i < 4; i++ )
{
for ( int j = 0; j < 10; j++ )
{
if ( s[i][j] )
{
size_t count = 0;
for ( char *p = s[i][j]; *p != '\0'; ++p )
{
if ( *p == 'a' ) ++count;
}
printf( "\"%s\": %zu\n", s[i][j], count );
}
}
}
printf( "\n" );
char* t[4] = { "abc", "aab", "cbb" };
for ( char **p = t; *p != NULL; ++p )
{
size_t count = 0;
for ( char *q = *p; *q != '\0'; ++q )
{
if ( *q == 'a' ) ++count;
}
printf( "\"%s\": %zu\n", *p, count );
}
printf( "\n" );
char u[4][10] = { "abc", "aab", "cbb" };
for ( int i = 0; i < 4; i++ )
{
if ( u[i][0] != '\0' )
{
size_t count = 0;
for ( char *p = u[i]; *p != '\0'; ++p )
{
if ( *p == 'a' ) ++count;
}
printf( "\"%s\": %zu\n", u[i], count );
}
}
return 0;
}
The program output is
"abc": 1
"aab": 2
"cbb": 0
"abc": 1
"aab": 2
"cbb": 0
"abc": 1
"aab": 2
"cbb": 0
It seems that you mean either the second variant of the array declaration or the third variant of the array declaration. The first variant looks strange.:)
Take into account that string literals already contain terminating zero. So there is no sense to write, for example
"abc\0"
It is enough to write simply
"abc"
The sizeof( "abc" ) is equal to 4 due to the presence of the terminating zero.
#include <stddef.h>
#include <stdio.h>
int main(int argc, char *argv[]) {
char s[10][4] = { "abc", "aab", "cbb" };
size_t i;
for (i = 0; i != sizeof(s) / sizeof(s[0]); i++) {
fprintf(stdout, "%zu: %s\n", i, s[i]);
}
return 0;
}
or
#include <stddef.h>
#include <stdio.h>
int main(int argc, char *argv[]) {
char *s[4] = { "abc", "aab", "cbb" };
size_t i;
for (i = 0; i != 3; i++) {
fprintf(stdout, "%zu: %s\n", i, s[i]);
}
return 0;
}
Note that the original declaration
char* s[4][10] = { "abc\0", "aab\0", "cbb\0" };
had several errors:
char * instead of char
[4][10] instead of [10][4]
"abc\0" instead of "abc" (the trailing '\0' is implicit).