Reputation:
basically I have a string composed of multiple words like this: "Hello world test"
.
Either if I try to print it with a structure like this
printf("%s", string);
or like this
for (int i = 0; i < strlen(string); ++i) {
printf("%c", string[i];
}
I always get this as an output: Hello world
and I get a strlen of 11 instead of 16 too.
If I try to print out the same exact string with an int counter that previously counts the single chars in the string
for (int i = 0; i < counter; ++i) {
printf("%c", string[i];
}
I actually get the correct output Hello world test
, which leads be to believe that the elements are correctly assigned in the string but for some reason %s and strlen just ignores the ones after the last space.
Why would that happen? What is going on? How can I fix this?
EDIT:
Actual code as requested:
#include <stdio.h>
#include <string.h>
typedef int BOOL;
#define TRUE 1
#define FALSE 0
int main() {
char sentence[64] = " ", reversal[64] = " ", reversal_copy[64] = " ";
int index = 0, counter = 0;
BOOL reset = TRUE, last_cycle = FALSE;
printf("Enter a sentence: ");
for (int i = 0; sentence[strlen(sentence) - 1] != '\n'; i++) {
scanf("%c", &sentence[i]);
}
/* Copies the input in a string reversing it */
for (int h = strlen(sentence) - 2, k = 0; h >= 0; h--, k++) {
reversal[k] = sentence[h];
}
/* Detects the first character of a word and the last character of the same word before a space,
switching the first char with the last, the second with the pre-last and so on*/
for (int i = 0; i < strlen(reversal); i++) {
if (reset == TRUE) {
index = i;
reset = FALSE;
}
if (i == strlen(reversal) - 1) {
last_cycle = TRUE;
counter++;
}
if (reversal[i] != ' ') {
counter++;
if (last_cycle == TRUE) {
goto reversing;
}
}
else {
reversing:
for (int h = index, z = counter; h < counter; h++, z--) {
reversal_copy[h] = reversal[z - 1];
reversal_copy[z - 1] = reversal[h];
}
if (last_cycle == FALSE) {
reversal_copy[i] = ' ';
}
reset = TRUE;
counter++;
}
}
printf("%lu ", strlen(reversal_copy));
for (int i = 0; i < counter; i++) {
printf("%c", reversal_copy[i]);
}
printf("%s\n\n", reversal_copy);
return 0;
}
Upvotes: 0
Views: 756
Reputation: 13144
the program takes a string inputted by the user like "the sky is blue" and prints out "blue is sky the"
That's a perfect job for strtok()
:
#include <stddef.h>
#include <stdio.h>
#include <string.h>
enum { MAX_LINE = 120 };
int main()
{
char buffer[MAX_LINE];
fgets(buffer, MAX_LINE, stdin);
size_t length = strlen(buffer);
if (length && buffer[length - 1] == '\n') // get rid of the newline
buffer[--length] = '\0';
char *tokens[MAX_LINE] = { 0 }; // there can't be more than 60 tokens, but hey
if ((tokens[0] = strtok(buffer, " ")) == NULL) // no tokens? nothing to do.
return 0;
size_t i = 1;
for (; tokens[i - 1] && i < sizeof(tokens); ++i)
tokens[i] = strtok(NULL, " "); // tokenize the buffer
--i; // the very last was NULL anyway.
while (--i) // print it reverse
printf("%s ", tokens[i]);
puts(buffer);
}
The quick brown fox jumps over the lazy dog
dog lazy the over jumps fox brown quick The
Upvotes: 0
Reputation: 35600
Try running your program with the input "A" as an example - see that even a single word exhibits the problem.
Something is going wrong when you reverse the last word. You are putting the trailing '\0'
in front of it. It probably has to do with the special casing and the goto
around the last_cycle
logic, which is very hard to follow.
I think it's probably related to the fact that you have two counter++
s in that code path.
Consider using some functions to make the code cleaner:
len = strlen(reversal);
for (start=0; start<len; start++) {
end = find_space_or_null(reversal, start);
if (end > start) {
reverse_chars(reversal, start, end-1);
start = end;
}
}
Upvotes: 0
Reputation: 21572
While this is difficult to answer without a Minimal, Complete, and Verifiable example, I will explain the most likely reason for the behavior you're observing.
Both printf
with the %s
format specifier and strlen
give you the length of the null-terminated string pointed to by the relevant argument. If they are printing/reporting a length of 11, but iterating through the entire char array with a hard-coded value of 16 gives you the output "hello world test", then the character after world is clearly the null character, '\0'.
Upvotes: 1
Reputation: 29266
if strlen()
returns 11 then you have a \0
char after the world "world".
strlen
and printf
both determine "what is a string" by using the 0 terminator, so no surprise that they behave the same.
Upvotes: 4