how to change a word in a string by its number? - c

I have this assignment:
Replace the numbered word in the sentence with three characters: ???
The problem is I can't replace the whole word by its number, my program changes only 3 first characters.
Here is my code:
#include <stdio.h>
#include <string.h>
int main() {
char sentence[100];
int word_number;
int pos;
int i;
printf("Enter sentence: ");
fgets(sentence, 100, stdin);
printf("Enter word number: ");
scanf("%d", &word_number);
pos = 0;
for (i = 0; i < strlen(sentence); i++) {
if (sentence[i] == ' ') {
word_number--;
}
if (word_number == 1) {
pos = i;
break;
}
}
// Update the sentence
sentence[pos] = '?';
sentence[pos + 1] = '?';
sentence[pos + 2] = '?';
printf("Result sentence: %s\n", sentence);
return 0;
}

There are multiple issues in the code:
Your approach only works if the word to be replaced has exactly 3 letters. For longer or shorter words, you need to move the contents of the remainder of the string.
Another restriction in your code is you assume that words a separated by a single space, which may of may not be explicitly stated in the assignment.
Similarly, you assume the n-th word is followed by a space, which may not be the case if the word is the last one in the sentence.
you should check the return values of fgets() and scanf() to detect invalid or missing input.
Here is a modified version.
#include <stdio.h>
#include <string.h>
int is_sep(char cc) {
// separators are space, newline and the null byte
return (cc == ' ' || cc == '\n' || cc == '\0');
// you could also accept punctuation as word separators:
//return strchr(" \t\n.,:;?!'`"##$%^&*()[]{}<>/`~+=|", cc);
}
int main() {
char sentence[200];
int word_number;
printf("Enter sentence: ");
// read a sentence, allow for 2 extra bytes to insert replacement
if (!fgets(sentence, sizeof(sentence) - 2, stdin))
return 1;
printf("Enter word number: ");
if (scanf("%d", &word_number) != 1)
return 1;
int len = strlen(sentence);
int start = 0;
int wn = 1;
char last = ' ';
for (int i = 0;; i++) {
char cc = sentence[i];
if (is_sep(cc)) {
if (!is_sep(last)) {
/* end of word */
if (wn == word_number) {
// replace this word with `???`
memmove(sentence + start + 3, sentence + i, len + 1 - i);
memcpy(sentence + start, "???", 3);
break;
}
wn++;
}
} else {
if (is_sep(last)) {
/* start of a word */
start = i;
}
}
last = cc;
if (cc == '\0')
break;
}
printf("Result sentence: %s\n", sentence);
return 0;
}

I’m not sure I’d try to do this in-place. For small data, it doesn’t hurt to just create a new buffer, even if it is just a temporary.
But, since we are posting solutions, here’s a single-pass version:
#include <iso646.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void replace_nth_word_with( char * dest, int n, const char * src, const char * word )
{
char last = ' ';
while (*src) // For each character in src:
if ((*src != ' ') and (last == ' ') and !n--) // If we found a word-begin AND it is the Nth word:
{ //
for (size_t k = 0; word[k]; k++) // Copy the new word to dest
*dest++ = word[k]; //
while (*src and (*src != ' ')) ++src; // Skip the old word in src
} //
else // Otherwise just copy the character over
last = *dest++ = *src++; //
*dest = '\0'; // End of string
}
void ask_string( const char * prompt, char * s, size_t n )
{
printf( "%s", prompt );
fgets( s, (int)n, stdin );
char * p = strpbrk( s, "\n\r" );
if (p) *p = '\0';
}
void ask_int( const char * prompt, int * n )
{
char s[20];
printf( "%s", prompt );
fgets( s, sizeof s, stdin );
*n = strtol( s, NULL, 10 );
// It hurts to write this without error checking, LOL
}
int main(void)
{
char sentence[1000];
ask_string( "Sentence? ", sentence, sizeof sentence );
int word_number;
ask_int( "Word number (counting from 1)? ", &word_number );
char new_word[100];
ask_string( "New word? ", new_word, sizeof new_word );
char new_sentence[sizeof sentence + sizeof new_word];
replace_nth_word_with( new_sentence, word_number-1, sentence, new_word );
printf( "\"%s\"\n", new_sentence );
return 0;
}

Related

How to write a function in c that counts words

I had an exam yesterday in which one of the questions was about counting words in a given string.
The definition of word would be a portion of a string that is divided by spaces and/or the beginning/end of the string
I am new to C, and was not able to create a condition where it increases the counter word when you find “space (characters) space”
int count_words(char *str)
int i = 0;
int word = 2;
while (str[i])
{
if (str[i] == ‘ ‘)
{
int l = 1;
while (str[i + l]
{
l++;
}
if (l != 1)
{
word++;
}
}
}
For starters the function should be declared like
size_t count_words(const char *str);
The function parameter should be declared with the qualifier const because the passed string is not being changed within the function and the function return type should be size_t that is the same return type as for example of standard string function strlen.
It is unclear why the variable word in your function is initialized by 2
int word = 2;
Or the variable i is not being changed within the function.
The function can look the following way as shown in the demonstration program below
#include <ctype.h>
#include <string.h>
#include <stdio.h>
size_t count_words( const char *s )
{
size_t n = 0;
while ( *s )
{
while ( isspace( ( unsigned char )*s ) ) ++s;
if ( *s )
{
++n;
while ( *s && !isspace( ( unsigned char )*s ) ) ++s;
}
}
return n;
}
int main( void )
{
const char *s = "How to write a function in c that counts words";
size_t n = count_words( s );
printf( "The string \"%s\"\ncontains %zu words\n", s, n );
}
The program output is
The string "How to write a function in c that counts words"
contains 10 words
If to use as delimiters only the space character ' ' then the header <ctype.h> should be removed and the function will look like
size_t count_words( const char *s )
{
size_t n = 0;
while ( *s )
{
while ( *s == ' ' ) ++s;
if ( *s )
{
++n;
while ( *s && *s != ' ' ) ++s;
}
}
return n;
}
A more general function that can process any delimiters can look the following way
size_t count_words( const char *s, const char *delim )
{
size_t n = 0;
while (*s)
{
s += strspn( s, delim );
if (*s)
{
++n;
s += strcspn( s, delim );
}
}
return n;
}
The function has a second parameter that specifies delimiters. For example the function can be called loke
size_t n = count_words( s, " \t?!:;,." );
Try this way:
# include<stdio.h>
# include<string.h>
# define MaxBufferSize 50
void main(){
int count =0, size;
char str[MaxBufferSize+2];
printf("Enter string(max char 50 only): ");
if(fgets(str,sizeof(str), stdin)) {
if(strlen(str) > MaxBufferSize) printf("Max chars exceeded so chars before the limit were used!!!\n");
str[strcspn(str, "\n")] = '\0';
}
size = strlen(str);
int i=0;
if(size == 0) printf("Nothing entered\n");
else {
while(i<size){
while(!isalnum(str[i]) && i<size) i++;// ignores all spaces and other chars
if(str[i] == '\0') break;
while(isalnum(str[i]) && i<size) i++;// includes all words and numbers
count++;
}
printf("Words in string: %d\n",count);
}
}
hope it helps...! ;)
#include <stdio.h>
int count_words(char *str) {
int i, count=0;
int in_word = 0; // Flag to track if we're currently inside a word or not
// Loop through each character in the string
for(i=0; str[i]!='\0'; i++) {
// If current character is not a space or newline and we're not already inside a word, increment word count
if((str[i]!=' ' && str[i]!='\n') && !in_word) {
count++;
in_word = 1; // Set flag to indicate we're currently inside a word
}
// If current character is a space or newline, set flag to indicate we're not inside a word
else if(str[i]==' ' || str[i]=='\n') {
in_word = 0;
}
}
return count;
}
#include <stdio.h>
#include <string.h>
void main()
{
char s[200];
int count = 0, i;
printf("Enter the string:\n");
scanf("%[^\n]s", s);
for (i = 0;s[i] != '\0';i++)
{
if (s[i] == ' ' && s[i+1] != ' ')
count++;
}
printf("Number of words in given string are: %d\n", count + 1);
}
Use this code it will definitely works fine ):

Reading In txt File and Extracting Elements from Input Problem

I have been attempting to fix this for hours. I am trying to read a file called wiktionary called "stuff.txt" which has input of the form:
10000
5627187200 the
3395006400 of
2994418400 and
2595609600 to
1742063600 in
...
The 10000 represents the number of lines. I am then reading it in using a function read_in_terms, and extracting the number (weight) and the word (word) from it. I have tested my get_word and get_weight functions seperately and they seem to be working. However, when I am reading in, my get_word function is not returning the word .... the get_weight number is...
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
char* concat(const char *s1, const char *s2) {
char *result = malloc(strlen(s1) + strlen(s2) + 1);
strcpy(result, s1);
strcat(result, s2);
return result;
}
// from a string of the form " 29480398934 the" it returns number
long get_weight(char *string) {
long length = strlen(string);
char number[200];
int count = 0;
// Here I am cycling through until X__X combination
// I only add to the number if it is not " "
for (int i = 0; i < length; i++) {
if (string[i-1] != ' ' && string[i] == ' ' && string[i+1] == ' ' && string[i+1] != ' ') {
break;
} else if (string[i] != ' '){
number[count] = string[i];
count++;
}
}
number[count] = '\0';
return atol(number); // converts it to a long and then returns
}
// from a string of the form " 453495834 word" it returns word
char * get_word(char* string) {
long length = strlen(string);
char word[200];
int count = 0;
// the double space detection only works once we reach a character
// this becomes 1 once that happens, allowing us to proceed to the next part
int blocker = 0;
for (int i = 0; i < length; i++) {
if (string[i] != ' '){
blocker++;
}else if (blocker > 0 && string[i] == ' ' && string[i+1] == ' ') {
int int_count = i+1;
while (string[int_count] != '\0') {
int_count++;
word[count] = string[int_count];
count++;
}
}
}
word[count] = '\0';
// now I need to copy this string into malloc
char *str = (char *)malloc(count*sizeof(char));
strcpy(str, word);
return str;
}
void read_in_terms(int *pnterms, char *filename) {
char part1[] = "/Users/adammartinez/Desktop/";
char* title = concat(part1,filename);
FILE *fp = fopen(title, "r");
char line[200];
fgets(line, sizeof(line), fp);
int num_lines = atoi(line);
for (int i = 0; i < num_lines; i++){
fgets(line, sizeof(line), fp);
printf("%ld \n", get_weight(line));
printf("%s \n", get_word(line)); // NOT RETURNING WORDS
}
}
int main(void) {
//char* test_str = " 547584758475 the";
//printf("%s %ld", get_word(test_str), get_weight(test_str));
int terms = 1000;
int *pointer = &terms;
read_in_terms(pointer, "stuff.txt");
return 0;
}
It seems to work fine on my computer. Please look at the output below and tell me if it's what you're looking for. I set part1 to "" and I changed the number of lines in stuff.txt to 5.
5627187200
the
3395006400
of
2994418400
and
2595609600
to
1742063600
in

How to print length of each word in a string before the each Word

I want to print the length of each word in a string.
I have tried but not getting right answer. After running the code it will print the length of each word after the word instead of printing before the each word.
char str[20] = "I Love India";
int i, n, count = 0;
n = strlen(str);
for (i = 0; i <= n; i++) {
if (str[i] == ' ' || str[i] == '\0') {
printf("%d", count);
count = 0;
} else {
printf("%c", str[i]);
count++;
}
}
I except the output is 1I 4Love 5India, but the actual output is I1 Love4 India5.
You can use strtok as Some programmer dude sugested. You may want to make a copy of the original string as strtok modifies the passed string. Also strtok is not thread-safe and must be replaced with strtok_r when working with multi-threaded programs.
#include <stdio.h>
#include <stdlib.h>
/* for strtok */
#include <string.h>
int main() {
char str[20] = "I Love India";
int n;
char* tok = strtok(str, " ");
while (tok != NULL) {
n = strlen(tok);
printf("%d%s ", n, tok);
tok = strtok(NULL, " ");
}
return EXIT_SUCCESS;
}
You want to compute and print the length of each word before you print the word.
Here is a simple solution using strcspn(), a standard function that should be used more often:
#include <stdio.h>
#include <string.h>
int main() {
char str[20] = "I Love India";
char *p;
int n;
for (p = str; *p;) {
if (*p == ' ') {
putchar(*p++);
} else {
n = strcspn(p, " "); // compute the length of the word
printf("%d%.*s", n, n, p);
p += n;
}
}
printf("\n");
return 0;
}
Your approach is wrong as you print the word before the length. So you need to calculate the length first then print it and then print the word.
It could be something like:
int main(void)
{
char str[20]="I Love India";
size_t i = 0;
while(str[i])
{
if (str[i] == ' ') // consider using the isspace function instead
{
// Print the space
printf(" ");
++i;
}
else
{
size_t j = i;
size_t count = 0;
// Calculate word len
while(str[j] && str[j] != ' ')
{
++count;
++j;
}
// Print word len
printf("%zu", count);
// Print word
while(i<j)
{
printf("%c", str[i]);
++i;
}
}
}
}
The basic idea is to have two index variables for the string, i and j. The index i is at the words first character and index j is used for finding the end of the word. Once the end of word has been found, the length and the word can be printed.
This is what you want:
#include <stdio.h>
#include <string.h>
int main()
{
char str[20]="I Love India";
char buf[20];
int i,n,count=0;
n=strlen(str);
for (i=0; i <= n; i++) {
if(str[i]==' ' || str[i]=='\0'){
buf[count] = '\0';
printf("%d", count); /* Print the size of the last word */
printf("%s", buf); /* Print the buffer */
memset(buf, 0, sizeof(buf)); /* Clear the buffer */
count = 0;
} else {
buf[count] = str[i];
count++;
}
}
return 0;
}
You will want to keep a buffer of the word that is currently being counted. (buf)
Increment count each time its not a space or 0/. Then, when it is a space or a 0/, print count first, then buf. Then, we will clear buf and set count to 0, so that the variable i is still incrementing through the entire string str, but we are inserting the words into buf starting from 0.

Reversing a two dimensional character array in C

i am trying to write a program which reverses a entire string and also may print reversing each word of the string more than one time.
For example my string is:
"2
Fox jumps over the lazy dog."
for this, the output should be:
.god .god yzal yzal eht eht revo revo spmuj spmuj xoF xoF.
I am trying to store each word in a 2d array and then reverse each word but i am not able to do that.
here is my code. kindly help
Note: how do we provide EOF in console
#include <stdio.h>
#include <stdlib.h>
int main() {
char string[100][100];
char ch;
int i = 0, j = 0, l = 0, count = 0, x = 0, y = 0;
while ((ch = getchar()) != EOF) {
string[i][l++] = ch;
if (ch == ' ') {
string[i][l] = '\n';
i++;
l = 0;
count++;
}
}
for (x = 0; x <= count; x++) {
int length = strlen(string[x]) - 1;
for (y = length; y >= 0; --y)
printf("%s", string[y]);
}
return 0;
}
Here are a few changes to your code check the comments for explanation.
int main()
{
char string[100][100];
char ch;
int i=0,j=0, l=0, count=0, x=0, y=0;
while((ch=getchar())!=EOF)
{
string[i][l++] = ch;
if(ch==' ')
{
string[i][l] = '\0'; //make the string null terminated otherwise you cant work with its length
i++;
l=0;
count++;
}
}
string[i][l]='\0'; //make the last string null terminated
for(x=count; x>=0; x--) //read from last counter
{
int length = strlen(string[x])-1;
for(y=length; y>=0; --y)
{
printf("%c", string[x][y]); //print by each character and not string.
}
}
return 0;
}
Corrections in your code:
C strings are null terminated, but you are terminating your strings with newline \n character, which is wrong.
You are storing the whitespace with the string, reversing will be difficult in this case.
Your print statement won't reverse the string, print it character by character.
For the output that you need, you can consider this code.
#include <stdio.h>
#include <stdlib.h>
int main() {
char string[100][100];
char ch;
int i = 0, j = 0, l = 0, count = 0, x = 0, y = 0;
while ((ch = getchar()) != EOF) {
if (ch == ' ') {
string[i][l] = '\0'; /// Null terminate the string
i++;
l = 0;
count++;
}
else
string[i][l++] = ch; /// Don't add whitespace to the string
}
string[i][l] = '\0';
for (x = count; x >= 0; x--) {
int length = strlen(string[x]) - 1;
for (y = length; y >= 0; --y)
printf("%c", string[x][y]); /// Print the string in reverse
printf(" ");
for (y = length; y >= 0; --y)
printf("%c", string[x][y]); /// Twice
printf(" ");
}
return 0;
}
Input
2 Fox jumps over the lazy dog.
Output
.god .god yzal yzal eht eht revo revo spmuj spmuj xoF xoF 2 2
See http://ideone.com/qaIoW9
If I understand you want to duplicate each reversed word N times as specified by the first number in the string, then something like the following would work:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *strrevdup (char* str);
int main (int argc, char **argv) {
if (argc < 2 ) {
fprintf (stderr, "error: insufficient input, usage: %s \"# string\"\n",
argv[0]);
return 1;
}
char *str = strdup (argv[1]);
char *p = str;
char *rev = NULL;
int mult = 0;
int i = 0;
while (*p && *p != ' ') p++;
*p = 0;
mult = atoi (str);
*p = ' ';
if (!mult) return 1;
while (*p && *p == ' ') p++;
rev = strrevdup (p);
char *r = rev;
printf ("\n the reversed string with duplicated words '%d' times is:\n\n", mult);
for (p = strtok (r, " "); p; p = strtok (NULL, " \n"))
for (i = 0; i < mult; i++)
printf (" %s", p);
printf ("\n\n");
free (str);
free (rev);
return 0;
}
/** strrevdup - reverse duplicate string, swaps src & dest each iteration.
* Takes valid string, duplicates and reverses, original is preserved.
* Returns pointer to reversed string on success, NULL otherwise.
* Requires string.h, caller is responsible for freeing memory allocated.
*/
char *strrevdup (char* str)
{
if (!str) {
printf ("%s() error: invalid string\n", __func__);
return NULL;
}
char *rstr = strdup (str);
char *begin = rstr;
char *end = rstr + strlen (rstr) - 1;
char tmp;
while (end > begin){
tmp=*end;
*end-- = *begin;
*begin++ = tmp;
}
return rstr;
}
Output
$ ./bin/strrevndup "2 Fox jumps over the lazy dog."
the reversed string with duplicated words '2' times is:
.god .god yzal yzal eht eht revo revo spmuj spmuj xoF xoF
you may try this code although it will reverse and print words in different lines.. you may try few more things to get the desired answer.
` #include <stdio.h>
#include <stdlib.h>
#include<string.h>
int main()
{
char string[1024][1024];
char ch;
int t,z;
scanf("%d",&t);
z=t;
int i=0, l=0, count=0, x=0, y=0;
getchar();
while((ch=getchar())!=EOF)
{
if(ch=='\n')
{
i++;
l=0;
count++;
string[i][l++] = ch;
i++;
l=0;
}
else if(ch==' ')
{
i++;
l=0;
count++;
}
else{
string[i][l++] = ch;
}
}
for(x=count+1; x>=0; x--)
{
if(string[x][0]=='\n')
{
printf("\n");
}
else{
char *rev=strrev(string[x]);
while(t--)
printf("%s ",rev);
t=z;
}
}
return 0;
}`

C: counting number of words (need help fixing)

I am new to C programming and trying to write a code for counting the number of words in a string.Here is my code for counting the number of codes.
#include<stdio.h>
#include<string.h>
void main()
{
int count=0,i,len;
char str[100];
printf("enter the sentence");
gets(str);
len=strlen(str);
for(i=0;i<=len;i++)
{
if(str[i]==' ')
count++;
}
printf("the number of words are :\t%d",count+1);
}
When my input is:Here is four words it works fine. it gives output
the number of words are : 4
My question is how do I handle "two consecutive spaces" between the word, "space at the beginning" of the input and "space at the last" of the input.
Instead of counting spaces, count the first non-space character of each word.
#include<stdio.h>
int main()
{
int count=0;
char str[100];
printf("enter the sentence");
gets(str);
char *cur= str;
for (;;)
{
while (*cur == ' ')
{
cur++;
}
if (*cur == 0)
{
break;
}
count++;
while (*cur != 0 && *cur != ' ')
{
cur++;
}
}
printf("the number of words are :\t%d",count);
return 0;
}
You can use:
while(str[i]==' '&&str[i]!=EOF)
{
count++;
i++;
}
instead of your if part. You also need to add these code before the for loop to read the beginning spaces.
I think the loop in the current form may not work properly,
It should be as follows,
for(i=0;i<len;i++)
{
if(i!=0)
{
if(str[i]==' ')
count++;
}
}
To check the other criteria change the code as follows,
for(i=0;i<len;i++)
{
if(str[i]==' ')
{
if(i!=0)
{
if(str[i+1]!=' ')
{
count++;
}
}
}
Just ignore spaces at the beginning and spaces directly after other spaces, and +1 if there are no spaces at the last.
#include <stdio.h>
#include <string.h>
// #include <stdlib.h>
int main() // void main is a bad practice
{
int count = 0, i, len, ignoreSpace;
char str[100];
printf("enter the sentence\n");
gets(str);
len = strlen(str);
ignoreSpace = 1; // handle space at the beginning
for(i = 0; i < len; i++) // not i<=len
{
if(str[i] == ' '){
if(!ignoreSpace){
count++;
ignoreSpace = 1; // handle two or more consecutive spaces
}
}else{
ignoreSpace = 0;
}
}
if( !ignoreSpace ) // handle space at the last
count++;
printf("the number of words are :\t%d\n", count); // +1 is moved to previous line
// system("pause");
return 0;
}
use strtok and first call of strtok use strtok(string," ") and for rest of calls use strtok(NULL, " \n")
You should count the transitions from space to non-space characters + a possible non-space character in the beginning itself.
#include<stdio.h>
#include<string.h>
int main()
{
int count=0,i,len, cur_is_spc;
char str[100];
printf("enter the sentence");
gets(str);
len=strlen(str);
cur_is_spc = 0; // 0, if current character is not space. 1, if it is.
for(i=0; str[i]!='\0'; i++)
{
if(str[i] != ' ')
{
switch(cur_is_spc) // currently holding value for previous character
{
case 0: count++; break; //count the spc->non-spc transitions
case 1: break;
default: cout << "Erroneous value"; exit(1);
}
cur_is_spc = 1; //updated for current character.
}
else
{
cur_is_spc = 0; //updated for current character.
}
}
printf("the number of words are :\t%d",count+1);
return 0;
}
Here, I am checking with only spaces. But there can be characters like newline, tab etc. How would your code handle them? Hint: use isspace() function.
/moreover, the transition can be done from non-alphabet characters to alphabet characters if you decide that words are made up of alphabets only. This approach is inherently flexible to suit your needs.
One quick way to do this is use strtok and break everything according to a predicate. This function satisfy all your requirements.
#include<stdio.h>
#include<string.h>
int countSpace(char* str){
int counter = 0;
char * newString;
newString= strtok (str, " "); // now the newString has the str except first word
while (newString != NULL){
counter++; // Put counter here to ignore the newString == NULL
// Or just -1 from the counter on main()
newString= strtok (NULL, " "); //Break the str in to words seperated by spaces
}
return counter;
}
void main(){
int count=0,i,len;
char str[100];
printf("Enter the sentence:\n");
fgets (str , 100 , stdin);
count = countSpace(str);
printf("The number of words are :\t%d\n",count);
return 0;
}
Thank you
Why not use strtok and bypass it altogether:
int main()
{
int num_words = 0;
char str_one[] = "This string has a trailing space ";
char str_two[] = " This string has a preceeding space";
char str_three[] = "This string contains two spaces consecutively twice!";
char delim[] = " ";
char *ret;
/* fgets() for user input as desired... */
if (( ret = strtok(str_one, delim)) != NULL )
{
while ( ret )
{
num_words++;
ret = strtok(NULL, delim);
}
}
else
{
/* no spaces, but might contain a word if the string isn't empty */
if ( str_one[0] != '\0' )
num_words = 1;
}
printf("str_one contains %i words\n", num_words);
num_words = 0;
...
return 0;
}
And by the way: main should ALWAYS return!!!

Resources