A program that prints even and odd characters from a string
Solution 1
this declaration is wrong:
char *str[41];
you're declaring 41 uninitialized strings. You want:
char str[41];
then, scanf("%40s" , str);
, no &
and limit the input size (safety)
then the loop (where your while (str[i]<41)
is wrong, it probably ends at once since letters start at 65 (ascii code for "A"). You wanted to test i
against 41 but test str[i]
against \0
instead, else you get all the garbage after nul-termination char in one of odd
or even
strings if the string is not exactly 40 bytes long)
while (str[i]) {
if (i % 2 == 0) {
odd[j++] = str[i];
} else {
even[k++] = str[i];
}
i++;
}
if you want to use a pointer (assignement requirement), just define str
as before:
char str[41];
scan the input value on it as indicated above, then point on it:
char *p = str;
And now that you defined a pointer on a buffer, if you're required to use deference instead of index access you can do:
while (*p) { // test end of string termination
if (i % 2 == 0) { // if ((p-str) % 2 == 0) { would allow to get rid of i
odd[j++] = *p;
} else {
even[k++] = *p;
}
p++;
i++;
}
(we have to increase i
for the even/odd test, or we would have to test p-str
evenness)
aaaand last classical mistake (thanks to last-minute comments), even
& odd
aren't null terminated so the risk of getting garbage at the end when printing them, you need:
even[k] = odd[j] = '\0';
(as another answer states, check the concept of even & odd, the expected result may be the other way round)
Solution 2
There are multiple problems in your code:
- You define an array of pointers
char *str[41]
, not an array ofchar
. - You should pass the array to
scanf
instead of its address: When passed to a function, an array decays into a pointer to its first element. - You should limit the number of characters read by
scanf
. - You should iterate until the end of the string, not on all elements of the array, especially with
(&str[i] < 41)
that compares the address of thei
th element with the value41
, which is meaningless. The end of the string is the null terminator which can be tested with(str[i] != '\0')
. - You should read the characters from
str
withstr[i]
. - You should null terminate the
even
andodd
arrays.
Here is a modified version:
#include <stdio.h>
int main(void) {
char str[41];
char odd[21];
char even[21];
int i = 0;
int j = 0;
int k = 0;
printf("Enter a string (40 characters maximum): ");
if (scanf("%40s", str) != 1)
return 1;
while (str[i] != '\0') {
if (i % 2 == 0) {
odd[j++] = str[i];
} else {
even[k++] = str[i];
}
i++;
}
odd[j] = even[k] = '\0';
printf("The even string is: %s\n", even);
printf("The odd string is: %s\n", odd);
return 0;
}
Note that your interpretation of even and odd characters assumes 1-based offsets, ie: the first character is an odd character. This is not consistent with the C approach where an even characters would be interpreted as having en even offset from the beginning of the string, starting at 0.
Solution 3
here is your solution :)
#include <stdio.h>
#include <string.h>
int main(void)
{
char str[41];
char odd[21];
char even[21];
int i = 0;
int j = 0;
int k = 0;
printf("Enter a string (40 characters maximum): ");
scanf("%s" , str);
while (i < strlen(str))
{
if (i % 2 == 0) {
odd[j++] = str[i];
} else {
even[k++] = str[i];
}
i++;
}
odd[j] = '\0';
even[k] = '\0';
printf("The even string is:%s\n " , even);
printf("The odd string is:%s\n " , odd);
return 0;
}
solved the mistake in the declaration, the scanning string value, condition of the while loop and assignment of element of array. :)
Solution 4
Many answers all ready point out the original code`s problems.
Below are some ideas to reduce memory usage as the 2 arrays odd[], even[]
are not needed.
As the "even" characters are seen, print them out.
As the "odd" characters are seen, move them to the first part of the array.
Alternative print: If code used "%.*s"
, the array does not need a null character termination.
#include <stdio.h>
#include <string.h>
int main(void) {
char str[41];
printf("Enter a string (40 characters maximum): ");
fflush(stdout);
if (scanf("%40s", str) == 1) {
int i;
printf("The even string is:");
for (i = 0; str[i]; i++) {
if (i % 2 == 0) {
str[i / 2] = str[i]; // copy character to an earlier part of `str[]`
} else {
putchar(str[i]);
}
}
printf("\n");
printf("The odd string is:%.*s\n ", (i + 1) / 2, str);
}
return 0;
}
or simply
printf("The even string is:");
for (int i = 0; str[i]; i++) {
if (i % 2 != 0) {
putchar(str[i]);
}
}
printf("\n");
printf("The odd string is:");
for (int i = 0; str[i]; i++) {
if (i % 2 == 0) {
putchar(str[i]);
}
}
printf("\n");
Related videos on Youtube
chrisHG
Updated on July 27, 2022Comments
-
chrisHG almost 2 years
This is for Homework
I have to write a program that asks the user to enter a string, then my program would separate the even and odd values from the entered string. Here is my program.
#include <stdio.h> #include <string.h> int main(void) { char *str[41]; char odd[21]; char even[21]; int i = 0; int j = 0; int k = 0; printf("Enter a string (40 characters maximum): "); scanf("%s", &str); while (&str[i] < 41) { if (i % 2 == 0) { odd[j++] = *str[i]; } else { even[k++] = *str[i]; } i++; } printf("The even string is:%s\n ", even); printf("The odd string is:%s\n ", odd); return 0; }
When I try and compile my program I get two warnings:
For my
scanf
I get"format '%s' expects arguments of type char but argument has 'char * (*)[41]"
. I'm not sure what this means but I assume it's because of the array initialization.On the
while
loop it gives me the warning that says comparison between pointer and integer. I'm not sure what that means either and I thought it was legal in C to make that comparison.
When I compile the program, I get random characters for both the even and odd string.
Any help would be appreciated!
-
Aditi Rawat over 6 years
scanf("%s" , &str);
->scanf("%s" , str);
-
Jean-François Fabre over 6 years
char *str[41];
=>char str[41];
then remove all dereferencing ofstr
(*str) -
chux - Reinstate Monica over 6 years
if (i % 2 == 0) { odd[j++] = str[i];
looks like it should beif (i % 2 == 0) { even[j++] = str[i];
-
Jay Joshi over 6 yearsplease edit your answer as you want to print the characters which is on place odd or even, not the values :)
-
Ed Heal over 6 yearsJust a question - For the even/odd big are we talking about the ASCII values or the characters '0' to '9' - Should be ignore 'A' etc...
-
chqrlie over 6 years@chux: actually, which array may not be null terminated depends on the length of the input ;-)
-
Jay Joshi over 6 yearsoh thank you for the suggestion. here.. i correct it
-
Jay Joshi over 6 yearssometimes it is easy to get the solution quickly instead of much explanation. that's my try :D ..he will surely figure out the problems.
-
Jean-François Fabre over 6 years@chqrlie "You should iterate until the end of the string, not on all characters": OP probably meant that, but actually OP tests
str[i]
against 41, so the loop probably ends at once, unless space or other lower ASCII chars are inputted. I didn't see why OP was doing that at first either... -
Jean-François Fabre over 6 yearsthis solution is wrong if the string entered isn't exactly 40 characters long.
-
chqrlie over 6 years@Jean-FrançoisFabre: indeed, the comparison was contorted and meaningless. the OP actually compares the address of
str[i]
with41
...