Hey everyone:

Can someone tell me why when I called printf in main I get a blank character. I ran this code in a C interpreter and it works fine, but when I compile with gcc and run it, it doesn't print out the new string. I get a empty string.

I've included the functions that are being called.

Thanks for the help.

int main() {
	char *test = "This is a test 12345";
	char *test2 = splitString(test);
	printf(test2);
}

char* splitString(char* string) {
	char *letterString = NULL;
	char *numberString = NULL;
	char *newString = NULL;
	int stringSize = strlen(string);
	
	newString = malloc(sizeof(char) * stringSize);

	if(newString == NULL) {
		printf("Memory couldnt be allocated");
	}
	
	letterString = findLettersAndPunctuation(string);
	numberString = findNumbers(string);
	strcat(newString, numberString);
	strcat(newString, letterString);
	printf(newString);
	//newString = strcat(numberString,letterString);
	free(letterString);
	free(numberString);
	return newString;
	
}

char* findLettersAndPunctuation(char* string) {
	char *letterString = NULL;
	int stringLength = strlen(string);
	int loopCounter = 0;
	int letterStringCounter = 0;
	
	letterString = malloc(sizeof(char) * (stringLength));
	
	if(letterString == NULL) {
		printf("Memory Could Not be allocated");
		exit(1);
	}
	
	for(loopCounter; loopCounter <= stringLength; loopCounter++) {
		if(isalpha(string[loopCounter]) == 1 || ispunct(string[loopCounter]) == 1
			|| isspace(string[loopCounter]) == 1) {
			letterString[letterStringCounter] = string[loopCounter];
			letterStringCounter++;
		}
	}
	letterString[letterStringCounter] = '\0';
	return letterString;
}

char* findNumbers(char* string) {
	char *numberString = NULL;
	int stringLength = strlen(string);
	int loopCounter = 0;
	int numberStringCounter = 0;
	
	numberString = malloc(sizeof(char) * stringLength);
	
	if(numberString == NULL) {
		printf("Memory Could Not be allocated");
		exit(1);
	}
	
	for(loopCounter; loopCounter <= stringLength; loopCounter++) {
		if(isdigit(string[loopCounter]) == 1) {
			numberString[numberStringCounter] = string[loopCounter];
			numberStringCounter++;
		}
	}
	numberString[numberStringCounter] = ' ';
	numberString[numberStringCounter + 1] = '\0';
	return numberString;
}

Dani AI

Generated

A short, practical summary that ties the thread together and explains the remaining pitfalls.

correctly pointed out that the ctype helpers return "nonzero" for true rather than the literal value 1; additionally these functions must be called with the character cast to unsigned char (or EOF) to avoid undefined behavior on systems where char is signed — see the isalpha man page for details.

The blank output in 's run comes from a combination of issues:

  • Destination for strcat was not an initialized C string and may not have had enough space. Always allocate enough bytes (remember the terminating NUL) and either zero the buffer (for example with calloc) or make it an empty string before concatenation.
  • Loops should iterate up to the actual characters, not past the NUL terminator.
  • Printing with printf(test2); uses the string as a format — this is unsafe and can silently fail if the string contains format specifiers. Use a format string instead:
    printf("%s\n", test2);
    if (isalpha((unsigned char)c)) { /* ... */ }

Memory-management note: freeing the temporary buffers that were separately malloced (the letter/number parts) is fine once their contents have been copied into the combined buffer. Do not free the buffer that is returned to the caller until the caller is done with it.

Quick checklist:

  • Cast characters: isalpha((unsigned char)ch).
  • Allocate sizes with strlen(...) + 1 (and extra bytes if inserting separators).
  • Initialize destination before strcat or use safer building functions.
  • Print with a format string: printf("%s", s).
    See the man pages for malloc, strcat and printf for behavior and safety notes: malloc, strcat, printf.

Recommended Answers

All 5 Replies

Well, its surprising, but here's the solution:
change all your if conditions to this:

if(isalpha(string[loopCounter]) || ispunct(string[loopCounter])	|| isspace(string[loopCounter]) )

i.e. dont check for == 1. The standard for isalpha (and other related functions) says that it returns a value other than zero; doesn't guarantee 1.

Strange, eh?

Thank you! I would have never caught that one. It was starting to drive me crazy.

The pleasure is all mine...:)
It was quite interesting actually...

Well, There are still a few more gotchas:
1. Do not free() numberString and letterString. You never malloc()'ed them. (try to run it in gcc, and you'll get a seg-fault)
2. Your strcat() wont work because newString is not yet a C-String. So at line 18 add this:

newString[0] = '\0';

3. Also, in your for loops, loop till loopCounter < stringSize (not <=). What you were doing was taking you outside the bounds of your array.
Hope that helps.

I was freeing those two pointers because they were returned from the two other functions that were called. I did what I needed to do with those two strings and freed them. It didn't cause a seg fault when I ran it.

Thanks

Right, it was giving me a seg-fault when newString[0] = '\0' was not done. After that change, free() is working fine.
My reasoning wsa wrong.
Should have checked...

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.