Ofek Ezon
Ofek Ezon

Reputation: 39

Program prints unrelated chars

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

Answers (3)

John Hascall
John Hascall

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;
}

Notes

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

anita2R
anita2R

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

stryku
stryku

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

Related Questions