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"
Related
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
char* string = "Hello, what's up?";
and I want to just return
"at's up?"
You can write a function. If the function shall not use standard C string functions then it can look for example the following way
char * substr( char *s, size_t pos )
{
size_t i = 0;
while ( i < pos && s[i] ) ++i;
return s + i;
}
As C does not support function overloading then the function above can be also written like
char * substr( const char *s, size_t pos )
{
size_t i = 0;
while ( i < pos && s[i] ) ++i;
return ( char * )( s + i );
}
Here is a demonstrative program.
#include <stdio.h>
char * substr( const char *s, size_t pos )
{
size_t i = 0;
while ( i < pos && s[i] ) ++i;
return ( char * )( s + i );
}
int main(void)
{
char * s = "Hello, what's up?";
puts( substr( s, 9 ) );
return 0;
}
The program output is
at's up?
If you already know the length of the string (and therefore know that going n characters ahead you will not go past the end), you can use string + n or &string[n], which are equivalent ways of "skipping" the first n characters of the string.
#include <stdio.h>
int main(void) {
char *str = "Hello!";
printf("%s\n", str + 1); // ello!
printf("%s\n", str + 3); // lo!
char *str2 = str + 3;
printf("%s\n", str2); // lo!
}
On the other hand, if you do not know the length of the string, you will have to make sure you don't go past the end by using a loop first. You can write a function for this:
#include <stdio.h>
char *skip(char *s, size_t n) {
while (*s && n--)
s++;
return s;
}
int main(void) {
char *str = "Hello!";
printf("%s\n", skip(str, 1)); // ello!
printf("%s\n", skip(str, 3)); // lo!
printf("%s\n", skip(str, 100)); // empty line
char *str2 = skip(str, 3);
printf("%s\n", str2); // lo!
}
Working on a program that uses RPN (Reverse Polish Notation).
I have a function that reverses all the words of string without using strtok or triggering printf (unlike all the solutions found online and here).
The function actually works partially as it prints all the words of a given string except the last one and I need help figuring out what's going on.
char *extract(char s[]) {
if (s[0] == '\0')
return NULL;
int i = 0;
char *p = NULL;
while (s[i] != '\0') {
if (s[i] == ' ')
p = s + i;
i++;
}
if (p != NULL) {
*p = '\0';
return p + 1;
}
}
And then it's called in main like this:
char s[MAX] = "5 60 +";
while(s != NULL){
printf("%s\n", extract(s));
}
The output is + 60 with the cursor endessly waiting for something
but the expected output should be + 60 5
A standard approach is to reverse each word within a string and then to reverse the whole string.
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 just started learning C after Java, so it's a little bit confusing to me. I tried to write a program with idea of counting the numbers of words which start with 'A' letter. The problem is that it only reads the first word I enter and ignore the rest of the sentence. Can somebody help me with this one? I would appreciate it.
#include <stdio.h>
#include <string.h>
void main() {
char sentence[200];
int i;
int counter = 0;
printf("Enter sentence: ");
scanf("%s", &sentence);
for (i = 0; sentence[i] != 0, sentence[i] != ' '; i++){
if (sentence[i] == 'A') {
counter = counter +1;
}
}
printf("No. of A in string %s > %d\n", sentence, counter);
return 0;
}
We beginners should help each other.:)
Here you are.
#include <stdio.h>
#include <string.h>
int main(void)
{
enum { N = 200 };
char sentence[N];
printf( "Enter sentence: " );
fgets( sentence, N, stdin );
size_t n = 0;
for ( const char *p = sentence; *p; p += strcspn( p, " \t" ) )
{
p += strspn( p, " \t" );
if ( *p == 'A' ) ++n;
}
printf("No. of A in string \"%s\" is %zu\n", sentence, n );
return 0;
}
The program output might look like
Enter sentence: Any word that starts with A
No. of A in string "Any word that starts with A" is 2
Also it is better to substitute the string literal " \t" for a named variable.
For example
#include <stdio.h>
#include <string.h>
int main(void)
{
enum { N = 200 };
char sentence[N];
char c = 'A';
const char *blank = " \t";
printf( "Enter sentence: " );
fgets( sentence, N, stdin );
size_t n = 0;
for ( const char *p = sentence; *p; p += strcspn( p, blank ) )
{
p += strspn( p, blank );
if ( *p == c ) ++n;
}
printf("No. of %c in string \"%s\" is %zu\n", c, sentence, n );
return 0;
}
You could write a separate function that does the task. The function declaration will look like
size_t count_words_start_with( const char *s, char c );
Here is a demonstrative program.
#include <stdio.h>
#include <string.h>
size_t count_words_start_with( const char *s, char c )
{
const char *blank = " \t";
size_t n = 0;
for ( const char *p = s; *p; p += strcspn( p, blank ) )
{
p += strspn( p, blank );
if ( *p == c ) ++n;
}
return n;
}
int main(void)
{
enum { N = 200 };
char sentence[N];
char c = 'A';
printf( "Enter sentence: " );
fgets( sentence, N, stdin );
printf("No. of %c in string \"%s\" is %zu\n",
c, sentence, count_words_start_with( sentence, c ) );
return 0;
}
Take into account that my answers almost always are the best answers.:)
Scan with strstr the string for words starting with "A" after empty space, then for the first word in the string:
...
fgets(sentence, sizeof(sentence), stdin);
int count = 0;
const char *tmp = sentence;
while(tmp = strstr(tmp, " A")) {
count++;
tmp++;
}
if (sentence[0] == 'A') count++;
...
This question already has answers here:
How to get substring in C
(4 answers)
Closed 7 years ago.
I have the following
char* str = "Some string";
How can I get a substring, from n to m symbols of str?
As following code:
int m = 2, n = 6;
char *p = (char *)malloc(sizeof(char) * (n - m));
for (size_t i = m; i < n; i++)
{
p[i - m] = str[i];
}
if(p)
printf("Memory Allocated at: %x/n",p);
else
printf("Not Enough Memory!/n");
free(p);
Here is a demonstrative program that shows how the function can be written.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
char * substr( const char *s, size_t pos, size_t n )
{
size_t length = strlen( s );
if ( !( pos < length ) ) return NULL;
if ( length - pos < n ) n = length - pos;
char *t = malloc( ( n + 1 ) * sizeof( char ) );
if ( t )
{
strncpy( t, s + pos, n );
t[n] = '\0';
}
return t;
}
int main(void)
{
char* s = "Some string";
char *t = substr( s, 0, strlen( s ) );
assert( strlen( s ) == strlen( t ) && strcmp( t, s ) == 0 );
puts( t );
free( t );
size_t n = 5, m = 10;
t = substr( s, n, m - n + 1 );
assert( strlen( t ) == m - n + 1 && strcmp( t, "string" ) == 0 );
puts( t );
free( t );
return 0;
}
The program output is
Some string
string
Try using this code
char *str = "Some string"
char temp[100];
char *ch1, *ch2;
ch1 = strchr(str,'m');
ch2 = strchr(str,'n');
len = ch2-ch1;
strncpy(temp,ch1,len);
char destStr[30];
int j=0;
for(i=n;i<=m;i++)
destStr[j++] = str[i];
destStr[j] = '\0';
Just copy the required characters using the loop as shown above. If you opt not to use the existing string family functions.
You can use strscpn function. Try this
int start, end;
start = strcspn(str, "m"); // start = 2
end = strcspn(str, "n"); // end = 9
char *temp = malloc(end-start + 2); // 9 - 2 + 1 (for 'n') + 1(for '\0')
strncpy(temp, &str[start], end-start + 1);
temp[end-start + 1] = '\0';