Count words from a string with multiple empty spaces - c

I need code that can count the words from a string without counting multiple spaces between them.
I could code a program that counts the words with only 1 empty space between them, but I don't know how I should code it when it would be more than 1 empty space. I thought something like a for loop that checks if the char before it is a space, but I don't know how to do that. And I want to mention that I'm a beginner in C.
#include <stdio.h>
#include <string.h>
int main()
{
char s[200];
int count = 0, i;
printf("enter the string: ");
fgets(s,200,stdin);
for (i = 0;s[i] != '\0';i++)
{
if (s[i] == ' ')
count++;
}
printf("number of words in given string are: %d\n", count+ 1);
return(0);
}

You can introduce a flag to tell whether the previous character was a space. Something like:
#include <stdio.h>
#include <string.h>
int main()
{
char s[200];
int count = 0, i;
int last_was_space = 1;
printf("enter the string: ");
fgets(s,200,stdin);
for (i = 0;s[i] != '\0';i++)
{
if (s[i] == ' ')
{
if (!last_was_space)
{
count++; // Only count when last char wasn't a space
last_was_space = 1;
}
}
else
{
// Update flag (unless this char is a newline)
if (s[i] != '\n') last_was_space = 0;
}
}
if (!last_was_space) ++count; // Count the last word if there wasn't a space before
printf("number of words in given string are: %d\n", count);
return(0);
}

Framing the problem in general terms helps here. Don't think of it as "counting words", or "counting spaces". Think of it as counting "transitions from separator to non-separator". Defining our terms:
Separator: start of string, or a single ASCII space
Non-separator: everything else
Examples (^ is start of string, _ is a literal space, $ is end of string):
^a_quick_brown_fox_jumps$
^ ^ ^ ^ ^ 5 transitions
^_a__quick___brownfox_jumps___$
^ ^ ^ ^ 4 transitions
^$
0 transitions
^___$
0 transitions
^__x$
^ 1 transition
Now in psuedo code:
def is_separator(char x):
return (x == NULL or x == ' ')
def is_non_separator(char x):
return (! is_separator(x))
let count = 0, last_char = NULL
while current_char = read_char():
if (is_non_separator(current_char) and is_separator(last_char)):
count++
From here, you can translate into specific languages or change the meaning of separators without affecting the logic of counting.

A bit more universal
size_t wcount(const char *s, const char *del, int countempty)
{
char *token;
size_t count = 0;
char *str = strdup(s);
if(str)
{
token = strtok(str, del);
while( token != NULL )
{
if(!strlen(token))
{
if(countempty)
{
count++;
}
}
else
{
count++;
}
token = strtok(NULL, del);
}
}
free(str);
return count;
}
int main ()
{
char str[] = "something to count ,., , . !! Stack overflow ";
printf("With empty %zu, Without empty%zu\n", wcount(str," ", 1), wcount(str," .,", 0));
}

count the words from a string without counting multiple spaces between them
Set a flag to determine if the beginning of a word is possible. Fewer special cases than looking for the end of the word.
Typically the requirement for "spaces" implies any white-space, then the task is easily coded:
#include <ctype.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
int main(void) {
char s[200];
printf("enter the string: ");
fgets(s, sizeof s, stdin);
int count = 0;
bool beginning_of_word_possible = true;
for (const char *p = s; *p; p++) {
if (isspace((unsigned char ) *p)) {
beginning_of_word_possible = true;
} else {
if (beginning_of_word_possible) {
count++;
}
beginning_of_word_possible = false;
}
}
printf("number of words in given string are: %d\n", count);
return (0);
}
#P__J__ offered a good idea that passes in a list of delimiters. Below is a similar and short solution that does not allocate memory nor change the supplied string.
#include <string.h>
size_t word_count(const char *s, const char *delimiters) {
size_t count = 0;
while (*(s += strspn(s, delimiters))) { // Advance s by the matching delimiters.
count++;
s += strcspn(s, delimiters); // Advance s by the non-matching delimiters.
}
return count;
}
Test
int main(void) {
const char *de = " \n";
printf("%zu\n", word_count("", de));
printf("%zu\n", word_count("\n", de));
printf("%zu\n", word_count(" ", de));
printf("%zu\n", word_count("abc", de));
printf("%zu\n", word_count(" abc", de));
printf("%zu\n", word_count(" abc \n", de));
printf("%zu\n", word_count("abc xyz", de));
printf("%zu\n", word_count(" abc xyz", de));
printf("%zu\n", word_count(" abc xyz \n", de));
}
Output
0
0
0
1
1
1
2
2
2

Short and Simple Version:
#include <stdio.h>
int main(void) {
char str[] = " Hello, This is a test of a word counter";
int i = 0;
for(char* s=str; strtok(s," "); i++) s = NULL;
printf("number of words in given string are: %d\n", i);
return 0;
}
Output
Success #stdin #stdout 0s 9424KB
number of words in given string are: 9

Related

comparing characters of a string with constant characters doesn't work

I am trying to calculate the number of sentences inside any text on the basis that the end of each sentence may be !, ? or ., but when I used strcmp() it doesn't work as expected. so if the text contains ! and compared with character constant ! it doesn't give the correct output as 0 as assumed.
Although, I tried to test the outputs to understand what took place led to such result but I couldn't understand so can anyone help ?
Thank you.
here is my code:
#include <cs50.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int count_sentences(string text);
int main(void)
{
string text = get_string("text: ");
//printf("%s\n", text);
count_sentences(text);
//printf("%i\n", strcmp("!", "!"));
}
int count_sentences(string text)
{
int string_length = strlen(text);
int num_of_sentences = 0;
const char sent_ind1 = '?';
const char sent_ind2 = '!';
const char sent_ind3 = '.';
//printf("%c %c %c", sent_ind1, sent_ind2,
//sent_ind3);
for (int i = 0; i < string_length; i++)
{
int value1 = strcmp(&text[i], &sent_ind1);
int value2 = strcmp(&text[i], &sent_ind2);
int value3 = strcmp(&text[i], &sent_ind3);
if (value1 == 0 || value2 == 0 || value3 == 0)
{
num_of_sentences += 1;
}
//printf("1- %i 2- %i 3- %i i- %c c- %c si0 %c si1 %c si2 %c\n",
//value1, value2, value3, i, text[i], sent_ind1, sent_ind2,
//sent_ind3);
//printf("1- %i 2- %i 3- %i i- %i\n",
//sent_ind1, sent_ind2, sent_ind3, text[i]);
}
//printf("string length equal %i and number of sentences equal %i.\n",
//string_length, num_of_sentences);
return num_of_sentences;
}
These records
int value1 = strcmp(&text[i], &sent_ind1);
int value2 = strcmp(&text[i], &sent_ind2);
int value3 = strcmp(&text[i], &sent_ind3);
does not make a sense. For starters the second arguments of the calls of strcmp do not point to strings.
Secondly even if they would point to strings the result of the calls will be equal to 0 only in one case when these characters '!', '?' and '.' are the last characters of the string text.
Instead of the function strcmp use functions strcspn and strspn.
For example the function can look the following way
#include <stdio.h>
#include <string.h>
size_t count_sentences( const char *text )
{
size_t n = 0;
const char *end_of_sentence = "!?.";
while ( ( text += strcspn( text, end_of_sentence ) ), *text != '\0' )
{
++n;
text += strspn( text, end_of_sentence );
}
return n;
}
int main( void )
{
const char *text = "Do you know C string functions? "
"Learn them!!! "
"They are useful.";
printf( "%zu\n", count_sentences( text ) );
}
The program output is
3
If you simply want to count a number of '!', '?' and '.' in the string you need to compare characters.
size_t count_sentences(string text)
{
size_t nos = 0;
size_t pos = 0;
while(text[pos])
{
if(text[pos] == '!' || text[pos] == '?' || text[pos] == '.') nos++;
pos++;
}
return nos;
}
strcmp compares the whole strings not looking for the substring in the string. In your case, you do not pass as a second parameter the string only the reference to single char (and it is not a valid string). It is an UB.
In addition to properly comparing a char with a char of a string answered elsewhere, consider a different way to count sentences.
How many sentences in these 2 strings?
No end punctuation
Screaming text!!! What???
To get 1 and 2 rather than 0 and 6. use ".?!" to enable an increment the next time a letter is seen.
size_t count_sentences1(const char *text) {
// Best to use unsigned char for is...()
const unsigned char *utext = (const unsigned char *) text;
size_t num_of_sentences = 0;
int start_of_sentence = 1;
while (*utext) {
if (isalpha(*utext)) {
num_of_sentences += start_of_sentence;
start_of_sentence = 0;
} else if (strchr(".?!", *utext)) {
start_of_sentence = 1;
}
utext++;
}
return num_of_sentences;
}
There are some 'clever' answers regarding "counting punctuation marks." Sadly, these would give an incorrect count when a sentence ends with an 'ellipse' ("...") or what some refer to as an "interobang" ("?!").
Without your CS50 library to test, I've a get_string() that returns a string complete with its trailing newline. This is 'optional' and needs to be adapted for your version of get_string().
// #include <cs50.h> // Don't have
#include <stdio.h>
#include <string.h>
int main() {
char *foo = get_string( "Enter several sentences: " );
foo[strlen(foo)-1] = '\0'; // Chop '\n' off if required
int count = 0;
while( strtok( foo, "?.!" ) )
count++, foo = NULL;
printf( "Number of sentences: %i.\n", count );
return 0;
}
Output:
Enter several sentences: Does. this! fulfill the? requirement????
Number of sentences: 4.

How to detect null values (and replace them) when reading from a file using sscanf [duplicate]

I am currently trying to parse UnicodeData.txt with this format: ftp://ftp.unicode.org/Public/3.0-Update/UnicodeData-3.0.0.html However, I am hitting a problem in that when I try to read, say a line like the following.
something;123D;;LINE TABULATION;
I try to get the data from the fields by code such as the following. The problem is that fields[3] is not getting filled in, and scanf is returning 2. in is the current line.
char fields[4][256];
sscanf(in, "%[^;];%[^;];%[^;];%[^;];%[^;];",
fields[0], fields[1], fields[2], fields[3]);
I know this is the correct implementation of scanf(), but is there a way to get this to work, short of making my own scanf()?
scanf does not handle "empty" fields. So you will have to parse it on your own.
The following solution is:
fast, as it uses strchr rather than the quite slow sscanf
flexible, as it will detect an arbitrary number of fields, up to a given maximum.
The function parse extracts fields from the input str, separated by semi-colons. Four semi-colons give five fields, some or all of which can be blank. No provision is made for escaping the semi-colons.
#include <stdio.h>
#include <string.h>
static int parse(char *str, char *out[], int max_num) {
int num = 0;
out[num++] = str;
while (num < max_num && str && (str = strchr(str, ';'))) {
*str = 0; // nul-terminate previous field
out[num++] = ++str; // save start of next field
}
return num;
}
int main(void) {
char test[] = "something;123D;;LINE TABULATION;";
char *field[99];
int num = parse(test, field, 99);
int i;
for (i = 0; i < num; i++)
printf("[%s]", field[i]);
printf("\n");
return 0;
}
The output of this test program is:
[something][123D][][LINE TABULATION][]
Update: A slightly shorter version, which doesn't require an extra array to store the start of each substring, is:
#include <stdio.h>
#include <string.h>
static int replaceSemicolonsWithNuls(char *p) {
int num = 0;
while ((p = strchr(p, ';'))) {
*p++ = 0;
num++;
}
return num;
}
int main(void) {
char test[] = "something;123D;;LINE TABULATION;";
int num = replaceSemicolonsWithNuls(test);
int i;
char *p = test;
for (i = 0; i < num; i++, p += strlen(p) + 1)
printf("[%s]", p);
printf("\n");
return 0;
}
Just in case you would like to consider this following alternative, using scanfs and "%n" format-specifier, used for reading in how many characters have been read by far, into an integer:
#include <stdio.h>
#define N 4
int main( ){
char * str = "something;123D;;LINE TABULATION;";
char * wanderer = str;
char fields[N][256] = { 0 };
int n;
for ( int i = 0; i < N; i++ ) {
n = 0;
printf( "%d ", sscanf( wanderer, "%255[^;]%n", fields[i], &n ) );
wanderer += n + 1;
}
putchar( 10 );
for ( int i = 0; i < N; i++ )
printf( "%d: %s\n", i, fields[i] );
getchar( );
return 0;
}
On every cycle, it reads maximum of 255 characters into the corresponding fields[i], until it encounters a delimiter semicolon ;. After reading them, it reads in how many characters it had read, into the n, which had been zeroed (oh my...) beforehand.
It increases the pointer that points to the string by the amount of characters read, plus one for the delimiter semicolon.
printf for the return value of sscanf, and the printing of the result is just for demonstration purposes. You can see the code working on http://codepad.org/kae8smPF without the getchar(); and with for declaration moved outside for C90 compliance.
I don't think sscanf will do what you need: sscanf format %[^;] will match a non-empty sequence of not-semicolon characters. The alternative would be using readline with the separator being ';', like:
#include <iostream>
#include <sstream>
#include <string>
int main() {
using namespace std;
istringstream i { "something;123D;;LINE TABULATION;\nsomething;123D;;LINE TABULATION;\nsomething;123D;;LINE TABULATION;\n" };
string a, b, c, d, newline;
while( getline(i, a, ';') && getline(i, b, ';') && getline(i, c, ';') && getline (i, d, ';') && getline(i, newline) )
cout << d << ',' << c << '-' << b << ':' << a << endl;
}
(I have only seen you took the c++ tag off this question now, if your problem is c-only, I have another solution, below:)
#include <string.h>
#include <stdio.h>
int main() {
typedef char buffer[2048];
buffer line;
while( fgets(line, sizeof(line), stdin) > 0 ) {
printf("(%s)\n", line);
char *end = line;
char *s1 = *end == ';' ? (*end = '\0'), end++ : strtok_r(end, ";", &end);
char *s2 = *end == ';' ? (*end = '\0'), end++ : strtok_r(end, ";", &end);
char *s3 = *end == ';' ? (*end = '\0'), end++ : strtok_r(end, ";", &end);
char *s4 = *end == ';' ? (*end = '\0'), end++ : strtok_r(end, ";", &end);
printf("[%s][%s][%s][%s]\n", s4, s3, s2, s1);
}
}

Issue with Strings in C

Here is a program with Strings where I am trying
Pig Latin translation is simply taking the first letter of a “word” and appending that letter to the end of the word with “ay” added to the end as well
I have issue with m1=m2+3 ( resetting the Initial Marker ).
Input that I am giving : "Alex, how are you right"
The output I am expecting is : lexay, owhay reay ouyay ightray
But
I am getting this : lex,Aay way ay ayo gayi
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
void initialize(char english[], char piglatin[]);
void readinput (char english[]);
int countwords(char english[]);
void convert ( int words, char english[], char piglatin[]);
void writeoutput( char piglatin[]);
int main()
{
char english[80], piglatin[80];
int words;
initialize(english, piglatin);
printf("enter the string\t");
fflush(stdin);
gets(english);
printf ("\nInput buffer contents: %s\n", english);
words = countwords(english);
convert(words,english,piglatin);
writeoutput(piglatin);
printf ("Have a nice day\n");
}
void initialize(char english[], char piglatin[])
{
int count;
for(count =0; count<80;++count)
{
english[count]=piglatin[count]=' ';
}
return;
}
/* Scan the english test and determine the number of words */
int countwords(char english[])
{
int count, words =1;
for ( count =0;count <79;++count)
{
if(english[count]==' ' && english[count+1]!=' ')
++words;
}
printf("%d\n",words);
return (words);
}
/* convert each words in to piglatin*/
void convert ( int words, char english[], char piglatin[])
{
int n, count;
int m1=0;
int m2;
/* convert each word */
for ( n=1;n<=words;++n)
{
/* locate the end of the current word*/
count = m1;
printf ("\ before conversion word contents: %d\n", count);
while ( english[count]!=' ')
{
m2=count++;
}
printf ("\ before conversion word contents: %d\n", m2);
/* transpose the first letter and add 'a', 'y'*/
for (count =m1;count<m2;++count)
{
piglatin[count+(n-1)]=english[count+1];
}
piglatin[m2+(n-1)] = english[m1];
piglatin[m2+1] = 'a';
piglatin[m2+2] = 'y';
m1=m2+3;
printf ("\ Converted word contents: %s\n", piglatin);
}
return;
}
void writeoutput( char piglatin[])
{
int count =0;
for (count =0; count <80; ++count)
{
putchar(piglatin[count]);
}
printf ("\n");
return;
}
I see various problems here:
Alex -> lex,Aay: You should check for punctuation marks when determining the end of the words, thus inserting the Aay part before the comma character
Alex -> lex,Aay: Every character from the start of a word should be converted to lowercase and the resulting first character should be converted to upper case respectively
Now the conversion function: I have changed it a bit to get you started; it should work now ( at least it does with your test string ) without taking 1 and 2 into account though
void convert(int words, char english[], char piglatin[])
{
int estart = 0;
int ppos = 0;
int m2;
for (int n = 0; n < words; n++)
{
//locate the start of the current word, to make
//sure something like this is converted:
//"Alex, how are you"
while (english[estart] == ' ')
{
//make sure we do not exceed the strings boundaries!
if (english[estart] == '\0')
{
return;
}
estart++;
}
//locate the end of the word
int eend = estart;
while (english[eend] != ' ')
{
//never forget to check for the end of the string
if (english[eend] == '\0')
{
break;
}
eend++;
}
/* transpose the first letter and add 'a', 'y'*/
for (int i = estart+1; i < eend; i++, ppos++)
{
piglatin[ppos] = english[i];
}
piglatin[ppos++] = english[estart];
piglatin[ppos++] = 'a';
piglatin[ppos++] = 'y';
//dont forget to add a whitespace or your string might behave
//very stangely!
piglatin[ppos++] = ' ';
estart = eend;
printf("\ Converted word contents: %s\n", piglatin);
}
}
I hope this gets you started in the right direction.
Please also check your array sizes for english and piglatin. The string for piglatin is alway longer than the english one but your array sizes are the same! Also i would advise you add some boundary checks to make sure you do not leave the array boundaries.

How to split a string into int[3]

I have a string, like "101 1 13" and I need to split it to a int aux[3] --> resulting in aux[0] = 101, aux[1] = 1 and aux[2] = 13 (in this case). How can
I do that?
In the example of the code below I get op as a String and want to get the value of the INTs in there. Each int is divided in the string by a white space(" ").
Another detail: I need the code to compile with flag -std=c99, so the answer that was accepted would not work.
#include <stdio.h>
#include <stdlib.h>
//example of str = "101 1 14" (char *)
// example of output = {101, 1, 14}(int *)
int* stoi(char *str) {
// function to split str into 3 ints
}
int main() {
char op[10];
int num[3];
scanf("%s\n", op);
num = stoi(op);
printf("%d %d %d", num[0], num[1], num[2]);
return 0;
}
First you need to tokenize your input (break apart the input into distinct elements). Then you need to parse/integerize the individual tokens by converting them from strings to the desired format.
Sample Code
#include <stdio.h>
#include <string.h>
#define BUF_LEN (64)
int main(void)
{
char buf[BUF_LEN] = { 0 };
char* rest = buf;
char* token;
int i = 0;
int iArr[100] = { 0 };
if ( fgets(buf, BUF_LEN, stdin) != NULL )
{
strtok(buf, "\n"); // Remove newline from input buffer in case we want to call fgets() again.
while ( (token = strtok_r(rest, " ", &rest)) != NULL )
{
iArr[i] = strtol(token, NULL, 10);
printf("Token %d:[%d].\n", i, iArr[i]);
i++;
}
}
return 0;
}
Sample Run
1231 12312 312 1232 1312
Token 0:[1231].
Token 1:[12312].
Token 2:[312].
Token 3:[1232].
Token 4:[1312].
Try to replace your code by following code.
The new code works only if input contains only single space between integers.
Your code:
while(op[cont] != '\0') {
for(i = 0; op[cont] != ' '; i++, cont++) {
num[i] += op[cont];
}
printf("num[i] = %d\n", num[i]);
}
New code:
while(op[cont] != '\0')
{
if(op[cont] != ' ')
num[i] = num[i]*10 + (op[cont]- '0');
else
i++;
cont++;
}
See this example of how to do that:
char string [10] = "101 1 666"
int v [3], n=0, j=0;
int tam = strlen(string);
int current_Len = 0;
for(i=0; i<tam; i++){
//32 = ascii for White space
if(string[i] != 32){
n = n*10 + string[i] - '0';
current_len++;
} else if (current_len > 0){
v[j++] = n;
current_len = 0;
n=0;
}
}
if (current_len > 0){
v[j++] = n;
}
This answer is assuming you know how much integers your string contain at the time of writing your code. It also uses specific clang/gcc extension (typeof) and may not be portable. But it may be helpful to someone (I mainly wrote it because I had nothing good to do).
#include <stdio.h>
#include <string.h>
struct {int _[3];} strToInt3(const char (*pStr)[])
{
int result[3] = {0}, *pr = result;
for(register const char *p = *pStr; *p; ++p)
{
if(*p == ' ') ++pr;
else
*pr *= 10,
*pr += *p - '0';
}
return *(__typeof__(strToInt3(0)) *)result;
}
int main()
{
char op[10];
int num[3];
scanf("%10[^\n]", op),
//memcpy(num, strToInt3(op)._, sizeof(num));
//or
*(__typeof__(strToInt3(0)) *)num = strToInt3(op);
printf("%d %d %d", num[0], num[1], num[2]);
}
I've commented the copying of returned array using memcpy and added a structure assignment. Although both must be valid (not standard I guess but working in most cases) I prefer the second option (and maybe some compiler optimizers will).
Also I assume ASCII character set for chars.
I found an easier approach to the problem. I insert a scanf, that don't catch the space blanket and convert it using atoi. As it is just 3 ints it doesn't become so bad to use this simple, repetitive way of catching the values. And it work with the -std=c99 flag, that I needed to use.
scanf("%s[^ ]\n", op);
num[0] = atoi(op);
scanf("%s[^ ]\n", op);
num[1] = atoi(op);
scanf("%s[^ ]\n", op);
num[2] = atoi(op);
printf("%d\n", num[0]);
printf("%d\n", num[1]);
printf("%d\n", num[2]);

Replacing a substring in a string - c

I'm trying to do a program which finds a substring in a string and replaces it with another substring entered by user. My code doesn't give a compile or run-time error, but it just doesn't work. I put printfs in the while loop which I wrote a comment line near it, and the program doesn't go into first if -I put another comment line near it. It prints a, h and i. The other parts in loop aren't working. Here's my code:
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
char *findAndReplace(char *sentence, char *word1, char *word2);
void main()
{
char sentence[1000];
char word1[200];
char word2[200];
int length;
printf("Please enter a sentence: ");
gets(sentence);
printf("Please write the word to be replaced: ");
gets(word1);
printf("Please write the word to be put instead: ");
gets(word2);
findAndReplace(sentence, word1, word2);
system("pause");
}
char* findAndReplace(char *sentence, char *word1, char *word2)
{
char *search, *tempString[1000];
int a, b, c, d, i = 0, j, sentenceLength, word1Length, searchLength;
sentenceLength = strlen(sentence);
printf("Length of %s is %d\n", sentence, sentenceLength);
printf("Finding ");
puts(word1);
search = strstr(sentence, word1);
searchLength = strlen(search);
word1Length = strlen(word1);
strcpy(tempString, sentence);
if(search != NULL)
{
printf("Starting point: %d\n", sentenceLength - searchLength);
}
else
{
printf("Eşleşme bulunamadı.\n");
}
j = 0;
while(j < sentenceLength + 1) //This loop
{
printf("a");
if(word1[i] == tempString[j])
{
printf("b");
if(i == word1Length)
{
c = j;
printf("c");
for(d = 0; d < word1Length; d++)
{
tempString[c - word1Length + d + 1] = word2[d];
printf("d");
}
i = 0;
j++;
printf("e");
}
else
{ printf("f");
i++;
j++;
}
printf("g");
}
else{
printf("h");
i = 0;
j++;
}
printf("i");
}
puts(tempString);
}
You've made a decent start, but you're making this a lot harder than it needs to be. One way to minimize errors is to rely on standard library functions when there are any that do the work you need done. For example:
char tempString[1000];
char *search;
search = strstr(sentence, word1);
if (search) {
ptrdiff_t head_length = search - sentence;
int sentence_length = strlen(sentence);
int word1_length = strlen(word1);
int word2_length = strlen(word2);
if (sentence_length + word2_length - word1_length < 1000) {
/* construct the modified string */
strncpy(tempString, sentence, head_length);
strcpy(tempString + head_length, word2);
strcpy(tempString + head_length + word2_length, search + word1_length);
/* copy it over the original (hope it doesn't overflow!) */
strcpy(sentence, tempString);
} else {
/* oops! insufficient temp space */
}
} /* else the target word was not found */
That covers only the search / replacement bit, fixing the error in tempString's type first pointed out by iharob. Also, it replaces only the first occurrence of the target word, as the original code appeared to be trying to do.
Among other things you have declared tempString as char* tempString[1000] which is an array of uninitialized character pointers so when you do
strcpy(tempString, sentence);
you are basically getting undefined behavior.
Use also fgets instead of gets when you input strings - even though you have rather large buffers it can happen one day that you pipe in a text file and get a stack overflow.
If I were you I would use strtok and split your sentence in words, then check each word. If word is same replace otherwise add sentence word to a new string.
e.g.
char newString[1000] = {0};
for (char* word = strtok(sentence, " "); word != NULL; word = strok(NULL, " "))
{
if (!strcmp(word, word1)) // here you may wanna use strncmp or some other variant
{
strcat(newString, word2);
}
else
{
strcat(newString, word);
}
strcat(newString, " ");
}
newString[strlen(newString)-1] = '\0';

Resources