The task was to reverse the order of words in the sentence
I was able to reverse the order of the words, but the problem is that the order of the letters in the word also changes
For example: cats and dogs
The miracle in my plan:tac dna sgod
The desired output: dogs and cats
How can I fix the code to work correctly?
this is my code:
void revSent(char str[]) {
int i;
int n = strlen(str);
char letter;
for (i = 0; i < n / 2; i++) {
letter = str[i];
str[i] = str[strlen(str) - i - 1];
str[strlen(str) - i - 1]=letter ;
}
}
You could split your sentence with the whitespace and then you can reorder the resulting array in reverse.
The usual approach is to reverse the whole string and then to reverse each word in the string separately.
To extract words in a string you can use standard string functions strspn and strcspn.
Here is a demonstration program
#include <stdio.h>
#include <string.h>
void reverse_n( char *s, size_t n )
{
for (size_t i = 0; i < n / 2; i++)
{
char c = s[i];
s[i] = s[n - i - 1];
s[n - i - 1] = c;
}
}
char *revSent( char *s )
{
const char *blank = " \t";
reverse_n( s, strlen( s ) );
for (char *p = s; *p; )
{
p += strspn( p, blank );
if (*p)
{
size_t n = strcspn( p, blank );
reverse_n( p, n );
p += n;
}
}
return s;
}
int main( void )
{
char s[] = "cats and dogs";
puts( s );
puts( revSent( s ) );
}
The program output is
cats and dogs
dogs and cats
Related
I am trying to reverse this C-string and I thought I did it correct but the string remains the same when it passes through the function.
#include <stdio.h>
char* reverse(char* string);
int main(int arc, char* argv[]) {
char word[] = "Hello World!";
printf("%s\n", word);
printf("%s\n", reverse(word));
return 0;
}
char* reverse(char* string) {
int i, j, n = 0;int len = 0;char temp;
//Gets string length
for (i = 0; *(string + i) != '0'; i++) {
len++;
}
//Reverses string
for (j = len - 1; j >= 0; j--) {
temp = string[n];
string[n] = string[j];
string[j] = temp;
n++;
}
return &string[0];
}
Expected output:
Hello World!
!dlroW olleH
For starters there is a typo
for (i = 0; *(string + i) != '0'; i++) {
You have to write
for (i = 0; *(string + i) != '\0'; i++) {
That is instead of the character '0' you have to use '\0' or 0.
In this for loop
for (j = len - 1; j >= 0; j--) {
temp = string[n];
string[n] = string[j];
string[j] = temp;
n++;
}
the string is reversed twice.:) As a result you get the same string.
The function can look for example the following way
char * reverse(char *string)
{
//Gets string length
size_t n = 0;
while ( string[n] != '\0' ) ++n;
//Reverses string
for ( size_t i = 0, m = n / 2; i < m; i++ )
{
char temp = string[i];
string[i] = string[n - i - 1];
string[n - i - 1] = temp;
}
return string;
}
Or the function can be defined the following way using pointers
char * reverse(char *string)
{
//Gets string length
char *right = string;
while ( *right ) ++right;
//Reverses string
if ( right != string )
{
for ( char *left = string; left < --right; ++left )
{
char temp = *left;
*left = *right;
*right = temp;
}
}
return string;
}
The same approach of the function implementation without using pointers can look the following way
char * reverse(char *string)
{
//Gets string length
size_t n = 0;
while ( string[n] != '\0' ) ++n;
//Reverses string
if ( n != 0 )
{
for ( size_t i = 0; i < --n; ++i )
{
char temp = string[i];
string[i] = string[n];
string[n] = temp;
}
}
return string;
}
Here is one more solution. I like it most of all. Tough it is inefficient but it is not trivial as the early presented solutions. It is based on an attempt of one beginner to write a function that reverses a string.:)
#include <stdio.h>
#include <string.h>
char *reverse( char *string )
{
size_t n = 0;
while (string[n]) ++n;
while (!( n < 2 ))
{
char c = string[0];
memmove( string, string + 1, --n );
string[n] = c;
}
return string;
}
int main( void )
{
char string[] = "Hello World!";
puts( string );
puts( reverse( string ) );
}
The program output is
Hello World!
!dlroW olleH
Of course instead of manually calculating the length of a string in all the presented solutions there could be used standard string function strlen declared in the header <string.h>.
The problem is that the input word[] is an array, which decays to a pointer when passed to the reverse function.
In the for loop, instead of using n to keep track of the position, I suggest you to use i and j to keep track of the start and end of the string, and increment and decrement them respectively and use strlen to get the length of string.
Also, as it is mentionned above by #Vlad from Moscow, in your for loop you are checking for 0 but it should be \0 which is the null character.
Please find down below an update of your posted code that is generating the expected result :
#include <stdio.h>
char* reverse(char* string);
int main(int arc, char* argv[]) {
char word[] = "Hello World!";
printf("%s ", word);
printf("%s\n", reverse(word));
return 0;
}
char* reverse(char* string) {
int i, j;
char temp;
int len = strlen(string);
//Reverses string
for (i = 0, j = len - 1; i < j; i++, j--) {
temp = string[i];
string[i] = string[j];
string[j] = temp;
}
return &string[0];
}
The output is as expected: Hello World! !dlroW olleH
Aditionnally, you can include the header <string.h> or explicitly
provide a declaration for 'strlen' to avoid the warning that indicate to implicitly declaring library function 'strlen' with type 'unsigned long (const char *)' [-Wimplicit-function-declaration]
The code is not working it didn't give accurate results. I don't know where is the problem or miss coding?
My input and output:
Enter a sentence :
hello im here to help you
heleh im here to help you
I used the following code,
int main()
{
/*
Enter a sentence to get reverse of each word
hello this is CPROGRAM Enjoy Programming
olleh siht si MARGORPC yojnE gnimmargorP
*/
char str[100];
printf("Enter a sentence : \n");
fgets(str, 100, stdin);
revwords(str);
fputs(str, stdout);
return 0;
}
void revwords(char* str){
int i = 0;
for(int j=1;str[j] != '\0';j++){
if( str[j] == ' ' || str[j] == '\t' || str[j] == '\n'){
rev(str, i, j-1);
i = j+1;
j++;
}
}
}
void rev(char* str, int from, int to){
char temp;
for(int i=from;i<= to/2;i++){
temp = str[i];
str[to-i] = str[i];
str[to-i] = temp;
}
}
Your rev function is broken in multiple ways:
void rev(char* str, int from, int to){
char temp;
for(int i=from;i<= to/2;i++){
temp = str[i];
str[to-i] = str[i];
str[to-i] = temp;
}
}
First: Your swapping is broken. You assign to str[to-i] twice and never in the other direction.
void rev(char* str, int from, int to){
char temp;
for(int i=from;i<= to/2;i++){
temp = str[i];
str[i] = str[to-i];
str[to-i] = temp;
}
}
Then your index is not calculated correct.
You seem to try to reverse from from to to but you treat to as if it was a length.
You need to use a separate index:
void rev(char* str, int from, int to){
char temp;
for(int i=0; i <= (to-from)/2; i++){
temp = str[from+i];
str[from+i] = str[to-i];
str[to-i] = temp;
}
}
Otherwise if you reverse from 10..15 you will copy to index 5..0 instead of 15..10
#include<stdio.h>
int main()
{
/*
Enter a sentence to get reverse of each word
hello this is CPROGRAM Enjoy Programming
olleh siht si MARGORPC yojnE gnimmargorP
*/
char str[100];
printf("Enter a sentence : \n");
//fgets(str, 100, stdin);
scanf("%[^\n]s", str);
revwords(str);
//fputs(str, stdout);
printf("%s\n",str);
return 0;
}
void revwords(char* str){
int i = 0;
for(int j=1;str[j] != '\0';j++){
if( str[j] == ' ' || str[j] == '\t' || str[j] == '\n'){
rev(str, i, j-1);
i = j+1;
j++;
}
}
}
void rev(char* str, int from, int to){
char temp;
while(from <= to){
temp = str[from];
str[from] = str[to];
str[to] = temp;
from++;
to--;
}
}
You can try this code. In your code in rev function swap is not done with correct way. And for input a line you can use scanf("%[^\n]s", str);.
Another bug in your code you are not reverse the last word. so outside the for loop in your revwords function need to reverse the last word. which is not fix this code, try yourself and if not able to find then please comment.
void revwords(char* str){
int i = 0;
int j;
for(j=1;str[j] != '\0';j++){
if( str[j] == ' ' || str[j] == '\t' || str[j] == '\n'){
rev(str, i, j-1);
i = j+1;
j++;
}
}
rev(str,i,j-1);
}
Change with this block of code and hope it will solve. it's just a modified version of your code.
The both functions, rev and revwords, are incorrect.
For example in general the user can pass an empty string. In this case the function revwords invokes undefined behavior due to the initial condition in the for loop
for(int j=1;str[j] != '\0';j++){
Also if the passed string does not contain white spaces that is it contains only one word then nothing will be reversed.
In the function rev the condition of the loop is incorrect
for(int i=from;i<= to/2;i++){
For example if form is equal to 3 and to is equal to 5 then the expression i <= to/2 yields 2 and the loop will never be executed.
Apart from this the code that swaps characters
temp = str[i];
str[to-i] = str[i];
str[to-i] = temp;
is also incorrect.
And at least the function revwords should have the return type char * following the convention of standard C string functions.
Take into account that the function fgets can append the new line character to the entered string. You should remove it.
Here is a demonstration program that shows how the functions can be implemented. I only renamed the function names.
#include <stdio.h>
#include <string.h>
static char * reverse( char *s, size_t n )
{
for ( size_t i = 0; i < n / 2; i++ )
{
char c = s[ i ];
s[ i ] = s[ n - i - 1 ];
s[ n - i - 1 ] = c;
}
return s;
}
char * reverse_by_words( char *s )
{
const char *delim = " \t\n";
char *p = s;
while ( *p )
{
p += strspn( p, delim );
if ( *p )
{
char *q = p;
p += strcspn( p, delim );
reverse( q, p - q );
}
}
return s;
}
int main(void)
{
enum { N = 100 };
char s[N];
printf( "Enter a sentence: " );
fgets( s, N, stdin );
// remove the appended new line character '\n'
s[ strcspn( s, "\n" ) ] = '\0';
puts( s );
puts( reverse_by_words( s ) );
return 0;
}
The program output might look like
Enter a sentence: hello im here to help you
hello im here to help you
olleh mi ereh ot pleh uoy
I was trying to reverse a sentence word by word. (how are you -> you are how) First of all I create a char sentence and reverse and temp. Sentence given by user to reverse. Temp catches the word to change the location in the sentence.Then I use strcat to concatenate each word. Here is the problem. I can find the word which is end of the sent(takes input) but when I'm trying to concatenate to reverse, it add this word to sentence and an error occurs. What's the problem?
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char* subs(char* temp, char* src, int start, int end);
int main() {
char sent[15]; //input sentence
char rev[15]; // output sentence
char *temp=(char*)calloc(1,sizeof(char)); //for the word
scanf(" %[^\n]%*c", &sent); // takin' input
int i, end, start;
i = strlen(sent);
//find the beggining and ending of the indexes of the word in sentence
while (i > 0) {
while (sent[i] == ' ') {
i--;
}
end = i-1;
while (sent[i] != ' ') {
i--;
}
start = i + 1;
//add the word to temp and concatenate to reverse
temp=subs(temp, sent, start, end);
strncat(rev, temp,end-start+3);
}
rev[strlen(sent)] = '\0';
printf("%s", rev);
return 0;
}
char* subs(char* temp, char* src, int start, int end) {
int i = 0, control;
// resize the temp for the wırd
temp = (char*)realloc(temp,end-start+3);
for (; i < (end - start) + 1; i++) {
control = (start + i);
temp[i] = src[control];
}
//adding blank and null character to end of the word.
temp[i] = ' ';
temp[++i] = '\0';
return temp;
}
I will just copy my good answer from this question that was not yet closed Reverse a string without strtok in C
. So I can not use this reference to close your question as a duplicate.
A standard approach is to reverse each word within a string and then to reverse the whole string.
The standard C function strtok is not appropriate in this case. Instead use the standard C functions strspn and strcspn.
Here you are.
#include <stdio.h>
#include <string.h>
static char * reverse( char *s, size_t n )
{
for ( size_t i = 0; i < n / 2; i++ )
{
char c = s[ i ];
s[ i ] = s[ n - i - 1 ];
s[ n - i - 1 ] = c;
}
return s;
}
char * reverse_by_words( char *s )
{
const char *delim = " \t";
char *p = s;
while ( *p )
{
p += strspn( p, delim );
if ( *p )
{
char *q = p;
p += strcspn( p, delim );
reverse( q, p - q );
}
}
return reverse( s, p - s );
}
int main(void)
{
char s[] = "5 60 +";
puts( s );
puts( reverse_by_words( s ) );
return 0;
}
The program output is
5 60 +
+ 60 5
If you want to keep leading and trailing spaces as they were in the original string then the functions can look the following way
#include <stdio.h>
#include <string.h>
static char *reverse( char *s, size_t n )
{
for ( size_t i = 0; i < n / 2; i++ )
{
char c = s[i];
s[i] = s[n - i -1 ];
s[n - i - 1] = c;
}
return s;
}
char * reverse_by_words( char *s )
{
const char *delim = " \t";
char *first = s, *last = s;
for ( char *p = s; *p; )
{
p += strspn( p, delim );
if ( last == s ) first = last = p;
if ( *p )
{
char *q = p;
p += strcspn( p, delim );
last = p;
reverse( q, p - q );
}
}
reverse( first, last - first );
return s;
}
int main(void)
{
char s[] = "\t\t\t5 60 +";
printf( "\"%s\"\n", s );
printf( "\"%s\"\n", reverse_by_words( s ) );
return 0;
}
The program output is
" 5 60 +"
" + 60 5"
I need to insert a character string to another character string.
I'd write my own code and it's work very well until I put SPACE character in insert character string.
I need to find out what is the problem of my code and How I can fix it.
//Insert string in another string
#include <stdio.h>
//Function to count number of characters in a string
int numOfChars(const char string[]);
//Function to insert string to another string
void insertString(char string[], char insert[], int position);
int main()
{
char str[20]= "145";
insertString(str, "23", 1);
printf("%s\n", str);
return 0;
}
int numOfChars(const char string[])
{
int counter = 0;
while(string[counter] != '\0')
counter++;
return counter;
}
void insertString(char string[], char insert[], int position)
{
int i, j;
int lenght1 = numOfChars(string);
int lenght2 = numOfChars(insert);
int finalLenght = lenght1 + lenght2;
for(i=lenght1, j=0; i<finalLenght; i++, position++, j++)
{
string[i] = string[position];
string[position] = insert[j];
}
string[finalLenght] = '\0';
}
Example 1 :
Main string : 145
Insert string : 23
Position : 2
Result : 12345
Example 2 with blank space :
Main string : 145
Insert string : 23[SPACE]
Position : 2
Result : 123 54
This loop
for(i=lenght1, j=0; i<finalLenght; i++, position++, j++)
{
string[i] = string[position];
string[position] = insert[j];
}
is incorrect because independent on the given position all characters from the source string stating at position position are written after the end of the source string.
Also the function insertString should be declared like
char * insertString(char string[], const char insert[], size_t position);
Here is a demonstrative program that shows how the function can be implemented.
#include <stdio.h>
size_t numOfChars( const char s[] )
{
size_t n = 0;
while ( s[n] != '\0' ) ++n;
return n;
}
char * insertString( char s1[], const char s2[], size_t pos )
{
size_t n1 = numOfChars( s1 );
size_t n2 = numOfChars( s2 );
if ( n1 < pos ) pos = n1;
for ( size_t i = 0; i < n1 - pos; i++ )
{
s1[n1 + n2 - i - 1] = s1[n1 - i - 1];
}
for ( size_t i = 0; i < n2; i++)
{
s1[pos+i] = s2[i];
}
s1[n1 + n2] = '\0';
return s1;
}
int main(void)
{
enum { N = 20 };
char s1[N] = "123";
puts( insertString( s1, "AB", 0 ) );
char s2[N] = "123";
puts( insertString( s2, "AB", 1 ) );
char s3[N] = "123";
puts( insertString( s3, "AB", 2 ) );
char s4[N] = "123";
puts( insertString( s4, "AB", 3 ) );
return 0;
}
The program output is
AB123
1AB23
12AB3
123AB
Changing string[i] = string[position]; to string[position+lenght2] = string[position]; should solve the problem.
While copying over the elements of string[i] to their proper places, the length of the string to insert should be considered in addition to the position variable. In other words, you should shift the characters in string by the number of elements that need to be inserted in the middle.
I need help to write a code that gets an array of unknown size and bubble sort it, every word between the spaces, ( only one space)
for example
bad dba = abd abd;
I wrote a code that gets a known size of strings,and I try to modify it and I can't think of anything.
Thanks in advance.!
my code so far is:
gets(strB);
do
{
flag = 0;
for
(q = 0; 'dont know what to put here'-J ; q++) {
if
(strB[q] > strB[q + 1])
{
// Swap
temp2 = strB[q];
strB[q] = strB[q + 1];
strB[q + 1] = temp2;
flag = 1;
}
}
j++;
} while
(flag != 0);
puts(strB);
We beginners should help each other.:)
If I have understood correctly you need to sort each word delimited by white spaces within a string.
You should write two functions. The first function splits a string into substrings and call a bubble sort function for each substring. The second function is a bubble sort function.
It can be done the following way
#include <stdio.h>
#include <ctype.h>
void bubble_sort( char *first, char *last )
{
for ( size_t n = last - first, sorted = n; !( n < 2 ); n = sorted )
{
for ( size_t i = sorted = 1; i < n; i++ )
{
if ( first[i] < first[i-1] )
{
char c = first[i];
first[i] = first[i-1];
first[i-1] = c;
sorted = i;
}
}
}
}
char * sort( char *s )
{
for ( char *p = s; *p; )
{
while ( isspace( ( unsigned char )*p ) ) ++p;
if ( *p )
{
char *q = p;
while ( *p && !isspace( ( unsigned char )*p ) ) ++p;
bubble_sort( q, p );
}
}
return s;
}
int main(void)
{
char s[] = "bad dba";
puts( s );
puts( sort( s ) );
return 0;
}
The program output is
bad dba
abd abd
Take into account that the function gets is an unsafe function and is not supported any more by the C Standard. Instead use the C standard function fgets.
To remove the appended new line character by the function fgets use the following trick
#include <string.h>
//...
fgets( s, sizeof( s ), stdin );
s[ strcspn( s, "\n" ) ] = '\0';
//...