Reputation: 39
I wanted to split an array to 2 arrays that the first one contains the lowercased letters of the original array and the second one contains the uppercased letters and from some reason it prints some unrelated chars.
#include <stdio.h>
#include <string.h>
#define LEN 8
int main(void)
{
char str[] = "SHaddOW";
char smallStr[LEN], bigStr[LEN];
int i = 0;
int indexSmall = 0;
int indexBig = 0;
for (i = 0; i <= LEN; i++)
{
if (str[i] <= 'Z')
{
smallStr[indexSmall] = str[i];
indexSmall++;
}
if (str[i] >= 'Z')
{
bigStr[indexBig] = str[i];
indexBig++;
}
}
printf("1: ");
puts(smallStr);
printf("2: ");
puts(bigStr);
system("PAUSE");
return 0;
}
Upvotes: 0
Views: 74
Reputation: 9416
A more compact approach with (perhaps) more meaningful variable names:
#include <stdio.h>
#include <ctype.h>
#include <stdint.h>
#include <string.h>
int main ( void ) {
const char str[] = "SHaddOW";
size_t len = strlen(str); /* better to get actual length */
char lowers[len + 1]; /* add one for the nul char */
char uppers[len + 1]; /* (see below) */
int c;
int i = 0;
int n_upper = 0;
int n_lower = 0;
while ((c = str[i++]) != '\0') {
if (isupper(c)) uppers[n_upper++] = c; /* no need to reinvent */
if (islower(c)) lowers[n_lower++] = c; /* the wheel here */
}
uppers[n_upper] = '\0'; /* the nul char ('\0') marks */
lowers[n_lower] = '\0'; /* the end of a C "string" */
printf("1: %s\n", lowers);
printf("2: %s\n", uppers);
return 0;
}
If you are super concerned about efficiency you could add an else
before if (islower...
Adding const
means you "promise" the characters in the array won't be changed.
The type size_t
is an integer type, but may be larger than int
. It is the correct type for the return of strlen()
. It is defined in <stdint.h>
. None the less, using int
will almost always work (on most systems a string would have to be 'yooooge' for its length to be bigger than an int can hold).
The variable c
is declared as int
instead of char
because int
is the proper type for the isXXXXX()
functions (which are defined in <ctype.h>
). It is also a good habit to get into because of the parallels between this loop and another common idiom while ((c = fgetc(fp)) != EOF) ...
.
Upvotes: 2
Reputation: 192
Don't define length before you create the string to test. Create it's length after defining the string to test.
Copy the characters as you encounter them, but as @Ed Heal says you must add a null terminator so that you can print out the two strings (they aren't really strings until they are null terminated).
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
int main (void)
{
char str[] = "SHaddOW";
int len = strlen(str) +1;
char smallStr[len], bigStr[len];
char term[] = {'\0'};
int n, s, b;
s=0;
b=0;
for(n=0; n<len; n++) {
if(islower(str[n])) {
memcpy(smallStr +s, str +n, 1);
s++;
} else if (isupper(str[n])){
memcpy(bigStr +b, str +n, 1);
b++;
}
}
memcpy(smallStr + s, term, 1);
memcpy(bigStr + b , term, 1 );
printf("Upper: %s\n", bigStr);
printf("Lower: %s\n", smallStr);
}
Output:
Upper: SHOW
Lower: add
Add this to the if structure (and other code to support it)
} else {
memcpy(anyStr +a, str +n, 1);
a++;
}
then:
char str[] = ".S1H2a3d4d5O6W.";
and:
printf("Anything else: %s\n", anyStr);
returns:
Upper: SHOW
Lower: add
Anything else: .123456.
Upvotes: 2
Reputation: 750
You should consider using isupper()
and islower()
functions. Code would be cleaner. And what if you have some non alpha characters? Your conditions won't work.
for (i = 0; i < LEN; i++)
{
if (islower(str[i]))
{
smallStr[indexSmall] = str[i];
indexSmall++;
}
else if (isupper(str[i]))
{
bigStr[indexBig] = str[i];
indexBig++;
}
}
As @Ed Heal mention. To avoid printing rubbish, after for loopt you should add a null characters to arrays.
smallStr[indexSmall] = '\0';
bigStr[indexBig] = '\0';
Upvotes: 0