Odd output of string in C - c

I received an assignment to write a code that would erase the instances of a string in another string, and although my code does that successfully, the symbol ╠ appears many times at the end of the result string.
Example:
For input string 1 - A string is a string, and an input string 2 - str
The result should be A ing is a ing.
But I receive A ing is a ing╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠
Hoped I could get some assistance regarding this issue, cause no matter what I've tried I wasn't able to
fix this.
#include <stdio.h>
#define STRING_SIZE 100
int StrippingFunc(char input_str1[STRING_SIZE], char input_str2[STRING_SIZE], char
result_string[STRING_SIZE])
{
if (input_str2[0] == '\n' || input_str2[0] == '\0')
{
return 0;
}
for (int k1 = 0; k1 < STRING_SIZE; k1++)
{
if (input_str1[k1] == '\n')
{
input_str1[k1] = '\0';
}
}
for (int k2 = 0; k2 < STRING_SIZE; k2++)
{
if (input_str2[k2] == '\n')
{
input_str2[k2] = '\0';
}
}
int Length;
int length2 = 0;
int index2 = 0;
while (input_str2[index2] != '\0') // Loop used to determine input_string2's length.
{
length2++;
index2++;
}
int InString = 0;
int i = 0;
int j;
int resultindex = 0;
while (input_str1[i] != '\0')
{
Length = length2;
int l = i;
j = 0;
int proceed = 1;
if (input_str1[l] == input_str2[j])
{
while ((input_str2[j] != '\0') && (proceed != 0))
{
while (Length >= 0)
{
if (Length == 0)
{
InString = 1;
i += (l-i-1);
proceed = 0;
Length = -1;
}
if (input_str1[l] == input_str2[j])
{
Length--;
j++;
l++;
}
else if ((input_str1[l-1] == input_str2[j-1]) && (input_str2[j] == '\0'))
{
proceed = 0;
Length = -1;
}
else
{
proceed = 0;
Length = -1;
result_string[resultindex] = input_str1[l - 1];
resultindex++;
}
}
}
}
else
{
result_string[resultindex] = input_str1[i];
resultindex++;
}
i++;
}
return InString;
}
int main()
{
char result_string[STRING_SIZE];
char input_string1[STRING_SIZE];
char input_string2[STRING_SIZE];
printf("Please enter the main string..\n");
// Your function call here..
fgets(input_string1, STRING_SIZE + 1, stdin);
printf("Please enter the pattern string to find..\n");
// Your function call here..
fgets(input_string2, STRING_SIZE + 1, stdin);
int is_stripped = StrippingFunc(input_string1, input_string2, result_string);; // Your function call here..
// Store the result in the result_string if it exists
printf("> ");
printf(is_stripped ? result_string : "Cannot find the pattern in the string!");
return 0;
}

But I receive A ing is a ing╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠
In the code after you fill result_string but you missed to add the final null character, because of that the printf after reach non initialized characters with an undefined behavior producing your unexpected writting. After
while (input_str1[i] != '\0')
{
Length = length2;
...
}
add
result_string[resultindex] = 0;
note you have the place for because result_string and input_str1 have the same size
Having
char input_string1[STRING_SIZE];
char input_string2[STRING_SIZE];
these two lines can have an undefined behavior :
fgets(input_string1, STRING_SIZE + 1, stdin);
fgets(input_string2, STRING_SIZE + 1, stdin);
because fgets may write after the end of the arrays, you need to remove +1 or to size the arrays one more
In
for (int k1 = 0; k1 < STRING_SIZE; k1++)
{
if (input_str1[k1] == '\n')
{
input_str1[k1] = '\0';
}
}
for (int k2 = 0; k2 < STRING_SIZE; k2++)
{
if (input_str2[k2] == '\n')
{
input_str2[k2] = '\0';
}
}
except if fgets fill all the arrays you have an undefined behavior working on non initialized characters because you do not stop when you reach newline or the null character.
In
int length2 = 0;
int index2 = 0;
while (input_str2[index2] != '\0') // Loop used to determine input_string2's length.
{
length2++;
index2++;
}
length2 and length2 have exactly the same value, is it useless to have two variables, and in fact this lop is useless because the previous loop with the right termination already give you the expected length.
In
printf(is_stripped ? result_string : "Cannot find the pattern in the string!");
I encourage you to replace printf by a puts not only to add a final newline to flush the output and make it more clear in case you start your program in a shell, but also because in case the input string contains for instance %d and it is not removed and is_stripped is true then printf will try to get an argument whose do not exist, with an undefined behavior
If you do all the corrections with your inputs your code will print > A ing is a ing without undefined behavior

Related

No syntax errors but code not showing the output

I wrote the code for multiple pre-defined functions, however, the output is not showing at all. What should I do?
Output message
It should be showing a text for the encrypted and decrypted messages but the output is blank there.
Here's the code:
#include "enigma.h"
const char *ROTOR_CONSTANTS[] = {
"ABCDEFGHIJKLMNOPQRSTUVWXYZ", // Identity Rotor (index 0 - and useful for testing):
"EKMFLGDQVZNTOWYHXUSPAIBRCJ",
"AJDKSIRUXBLHWTMCQGZNPYFVOE",
"BDFHJLCPRTXVZNYEIWGAKMUSQO",
"ESOVPZJAYQUIRHXLNFTGKDCMWB",
"VZBRGITYUPSDNHLXAWMJQOFECK",
"JPGVOUMFYQBENHZRDKASXLICTW",
"NZJHGRCXMYSWBOUFAIVLPEKQDT",
"FKQHTLXOCBJSPDZRAMEWNIUYGV",
};
void String_func(int flag, char in[], char out[]) {
flag = (flag > 0) ? flag : 0;
int i = 0;
for (int i = 0; in[i] != '\0'; i++) {
out[i+flag] = in[i];
}
out[i+flag] = '\0';
}
// This method reads a character string from the keyboard and
// stores the string in the parameter msg.
// Keyboard input will be entirely uppercase and spaces followed by
// the enter key.
// The string msg should contain only uppercase letters spaces and
// terminated by the '\0' character
// Do not include the \n entered from the keyboard
void Get_Message(char msg[]){
int i = 0;
char ch;
while ((ch=getchar()) != '\n') {
msg[i] = ch;
++i;
}
msg[i] = '\0';
return;
}
// This function reads up to 4 characters from the keyboard
// These characters will be only digits 1 through 8. The user
// will press enter when finished entering the digits.
// The rotor string filled in by the function should only contain
// the digits terminated by the '\0' character. Do not include
// the \n entered by the user.
// The function returns the number of active rotors.
int Get_Which_Rotors(char which_rotors[]){
char arr[5];
scanf("%4s", arr);
int value = 0; //stores integer value of which rotor to be called
int i = 0;
while (arr[i] != '\0') {
if (arr[i] != ' ')
value++;
i++;
}
String_func(0, arr, which_rotors);
return value;
}
// This function reads an integer from the keyboard and returns it
// This number represents the number of rotations to apply to the
// encryption rotors. The input will be between 0 and 25 inclusive
int Get_Rotations(){
int rot; //rotations
scanf("%d", &rot);
return rot;
}
// This function copies the rotors indicated in the which_rotors string
// into the encryption_rotors. For example if which rotors contains the string
// {'3', '1', '\0'} Then this function copies the third and first rotors into the
// encryption rotors array in positions 0 and 1.
// encryptions_rotors[0] = "BDFHJLCPRTXVZNYEIWGAKMUSQO"
// encryptions_rotors[1] = "EKMFLGDQVZNTOWYHXUSPAIBRCJ"
void Set_Up_Rotors(char encryption_rotors[4][27], char which_rotors[5]){
int i, enc = 0;
i = 0;
while (which_rotors[i] != '\0') {
if (which_rotors[i] != ' ') {
String_func(0, ROTOR_CONSTANTS[int(which_rotors[i])], encryption_rotors[enc++]);
}
i++;
}
if (i < 3) {
int j = i;
while (j <= 3) {
encryption_rotors[j][0] = '\0';
++j;
}
}
return;
}
// This function rotates the characters in each of the active encryption rotors
// to the right by rotations. For example if rotations is 3 encryption_rotors[0]
// contains "BDFHJLCPRTXVZNYEIWGAKMUSQO" then after rotation this row will contain
// SQOBDFHJLCPRTXVZNYEIWGAKMU. Apply the same rotation to all for strings in
// encryption_rotors
void Apply_Rotation(int rotations, char encryption_rotors[4][27]) {
int index = 0;
int i = 0;
char rot[rotations+1];
char rotator[27+rotations];
while (encryption_rotors[i][0] != '\0') {
int j = 26-rotations;
while (j < 26) {
rot[index++] = encryption_rotors[i][j];
++j;
}
rot[index] = '\0';
String_func(rotations, encryption_rotors[i], rotator);
int k = 0;
while (j < rotations) {
rotator[k] = rot[k];
++k;
}
rotator[26] = '\0';
String_func(0, rotator, encryption_rotors[i]);
index = 0;
++i;
}
return;
}
// This function takes a string msg and applys the enigma machine to encrypt the message
// The encrypted message is stored in the string encryped_msg
// Do not change spaces, make sure your encryped_msg is a \0 terminated string
void Encrypt(char encryption_rotors[4][27], int num_active_rotors, char msg[], char encrypted_msg[]){
String_func(0, msg, encrypted_msg);
int i = 0;
while (i < num_active_rotors) {
int j = 0;
while (encrypted_msg[j] != '\0') {
if (encrypted_msg[j] == ' ')
continue;
int index = encrypted_msg[j] - 65;
encrypted_msg[j] = encryption_rotors[i][index];
++j;
}
++i;
}
return;
}
// This function takes a string msg and applys the enigma machine to decrypt the message
// The encrypted message is stored in the string encryped_msg and the decrypted_message
// is returned as a call by reference variable
// remember the encryption rotors must be used in the reverse order to decrypt a message
// Do not change spaces, make sure your decrytped_msg is a \0 terminated string
void Decrypt(char encryption_rotors[4][27], int num_active_rotors, char encrypted_msg[], char decrypted_msg[]) {
String_func(0, encrypted_msg, decrypted_msg);
int i = num_active_rotors - 1;
while (i >= 0) {
int j = 0;
while (decrypted_msg[j] != '\0') {
if(decrypted_msg[j] == ' ')
continue;
int whichIndex = LookForIndex(decrypted_msg[j], encryption_rotors[i]);
decrypted_msg[j] = ROTOR_CONSTANTS[0][whichIndex];
++j;
}
--i;
}
}
And the code for the driver is this:
#include "enigma.h"
int main() {
char message[80];
char encrypted_message[80];
char decrypted_message[80];
char which_rotors[5];
char encryption_rotors[4][27];
int rotations;
int num_active_rotors;
printf("Enter the message to be encrypted or decrypted: ");
Get_Message(message);
printf("\nWhich rotors will be used to encrypt the message: ");
num_active_rotors = Get_Which_Rotors(which_rotors);
printf("\nEnter the number of rotations to apply to the encryption rotors: ");
rotations = Get_Rotations();
Set_Up_Rotors(encryption_rotors, which_rotors);
Apply_Rotation(rotations, encryption_rotors);
Encrypt(encryption_rotors, num_active_rotors, message, encrypted_message);
Decrypt(encryption_rotors, num_active_rotors, encrypted_message, decrypted_message);
printf("The encrypted message is: %s", encrypted_message);
printf("The decrypted message is: %s", decrypted_message);
return 0;
}
Do I edit the enigma_driver.c? I am really unsure what is going on as c is very new to me and it took a lot of time to write this project.
int i = 0;
for (int i = 0; in[i] != '\0'; i++) {
out[i+flag] = in[i];
}
out[i+flag] = '\0';
You have two variables called i. The one declared in the for statement is the one that gets incremented. So when you execute the last line, i is always zero.

Program to count length of each word in string in C

I'm writting a program to count the length of each word in array of characters. I was wondering if You guys could help me, because I'm struggling with it for at least two hours for now and i don't know how to do it properly.
It should go like that:
(number of letters) - (number of words with this many letters)
2 - 1
3 - 4
5 - 1
etc.
char tab[1000];
int k = 0, x = 0;
printf("Enter text: ");
fgets(tab, 1000, stdin);
for (int i = 2; i < (int)strlen(tab); i++)
{
for (int j = 0; j < (int)strlen(tab); j++)
{
if (tab[j] == '\0' || tab[j]=='\n')
break;
if (tab[j] == ' ')
k = 0;
else k++;
if (k == i)
{
x++;
k = 0;
}
}
if (x != 0)
{
printf("%d - %d\n", i, x);
x = 0;
k = 0;
}
}
return 0;
By using two for loops, you're doing len**2 character scans. (e.g.) For a buffer of length 1000, instead of 1000 character comparisons, you're doing 1,000,000 comparisons.
This can be done in a single for loop if we use a word length histogram array.
The basic algorithm is the same as your inner loop.
When we have a non-space character, we increment a current length value. When we see a space, we increment the histogram cell (indexed by the length value) by 1. We then set the length value to 0.
Here's some code that works:
#include <stdio.h>
int
main(void)
{
int hist[100] = { 0 };
char buf[1000];
char *bp;
int chr;
int curlen = 0;
printf("Enter text: ");
fflush(stdout);
fgets(buf,sizeof(buf),stdin);
bp = buf;
for (chr = *bp++; chr != 0; chr = *bp++) {
if (chr == '\n')
break;
// end of word -- increment the histogram cell
if (chr == ' ') {
hist[curlen] += 1;
curlen = 0;
}
// got an alpha char -- increment the length of the word
else
curlen += 1;
}
// catch the final word on the line
hist[curlen] += 1;
for (curlen = 1; curlen < sizeof(hist) / sizeof(hist[0]); ++curlen) {
int count = hist[curlen];
if (count > 0)
printf("%d - %d\n",curlen,count);
}
return 0;
}
UPDATE:
and i don't really understand pointers. Is there any simpler method to do this?
Pointers are a very important [essential] tool in the C arsenal, so I hope you get to them soon.
However, it is easy enough to convert the for loop (Removing the char *bp; and bp = buf;):
Change:
for (chr = *bp++; chr != 0; chr = *bp++) {
Into:
for (int bufidx = 0; ; ++bufidx) {
chr = buf[bufidx];
if (chr == 0)
break;
The rest of the for loop remains the same.
Here's another loop [but, without optimization by the compiler] double fetches the char:
for (int bufidx = 0; buf[bufidx] != 0; ++bufidx) {
chr = buf[bufidx];
Here is a single line version. Note this is not recommended practice because of the embedded assignment of chr inside the loop condition clause, but is for illustration purposes:
for (int bufidx = 0; (chr = buf[bufidx]) != 0; ++bufidx) {

How to get words out of a string and put them in an string array ? In C

I basically have a sentence in a string and want to break it down word per word. Every word should go into an array of strings. I am not allowed to use strtok. I have this code but it doesn't work. Can someone help?
There is for sure something similar in the internet but I couldn't find anything...
int main(){
char s[10000]; // sentence
char array[100][100]; // array where I put every word
printf("Insert sentence: "); // receive the sentence
gets(s);
int i = 0;
int j = 0;
for(j = 0; s[j] != '\0'; j++){ // loop until I reach the end
for(i = 0; s[i] != ' '; i++){ // loop until the word is over
array[j][i] = s[i]; // put every char in the array
}
}
return 0;
}
Every word should go into an array of strings. I am not allowed to use
strtok.
Interesting problem which could be resolved in a compact algorithm.
It handles multiple spaces and punctuation marks specified in check(char c).
The most difficult part of the problem is to properly handle corner cases. We may have situation when words are longer more than WORD_LEN length or the number of words exceeds the capacity of the array.
Both cases are properly handled. The algorithm truncates the excessive words and parses only to the capacity of the array.
(BTW. Do not use gets: Why is the gets function so dangerous that it should not be used?)
Edit: The fully tested find_tokens function has been presented.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define WORD_LEN 3 // 100 // MAX WORD LEN
#define NR_OF_WORDS 3 // 100 // MAX NUMBER OF WORDS
#define INPUT_SIZE 10000
int is_delimiter(const char * delimiters, char c) // check for a delimiter
{
char *p = strchr (delimiters, c); // if not NULL c is separator
if (p) return 1; // delimeter
else return 0; // not a delimeter
}
int skip(int *i, char *str, int skip_delimiters, const char *delimiters)
{
while(1){
if(skip_delimiters) {
if( (str[(*i)+1] =='\0') || (!is_delimiter(delimiters, str[(*i)+1])) )
break; // break on nondelimeter or '\0'
else (*i)++; // advance to next character
}
else{ // skip excess characters in the token
if( is_delimiter(delimiters, str[(*i)]) )
{
if( (str[(*i)+1] =='\0') || !is_delimiter(delimiters, str[(*i)+1]) )
break; // break on non delimiter or '\0'
else (*i)++; // skip delimiters
}
else (*i)++; // skip non delimiters
}
}
if ( str[(*i)+1] =='\0') return 0;
else return 1;
}
int find_tokens(int max_tokens, int token_len, char *str, char array[][token_len+1], const char *delimiters, int *nr_of_tokens)
{
int i = 0;
int j = 0;
int l = 0;
*nr_of_tokens = 0;
int status = 0; // all OK!
int skip_leading_delimiters = 1;
int token = 0;
int more;
for(i = 0; str[i] != '\0'; i++){ // loop until I reach the end
// skip leading delimiters
if( skip_leading_delimiters )
{
if( is_delimiter( delimiters, str[i]) ) continue;
skip_leading_delimiters = 0;
}
if( !is_delimiter(delimiters,str[i]) && (j < token_len) )
{
array[l][j] = str[i]; // put char in the array
//printf("%c!\n", array[l][j] );
j++;
array[l][j] = 0;
token = 1;
}
else
{
//printf("%c?\n", str[i] );
array[l][j] = '\0'; // token terminations
if (j < token_len) {
more = skip(&i, str, 1, delimiters); // skip delimiters
}
else{
more = skip(&i, str, 0, delimiters); // skip excess of the characters in token
status = status | 0x01; // token has been truncated
}
j = 0;
//printf("more %d\n",more);
if(token){
if (more) l++;
}
if(l >= max_tokens){
status = status | 0x02; // more tokens than expected
break;
}
}
}
if(l>=max_tokens)
*nr_of_tokens = max_tokens;
else{
if(l<=0 && token)
*nr_of_tokens = 1;
else
{
if(token)
*nr_of_tokens = l+1;
else
*nr_of_tokens = l;
}
}
return status;
}
int main(void){
char input[INPUT_SIZE+1]; // sentence
char array[NR_OF_WORDS][WORD_LEN+1]; // array where I put every word, remeber to include null terminator!!!
int number_of_words;
const char * delimiters = " .,;:\t"; // word delimiters
char *p;
printf("Insert sentence: "); // receive the sentence
fgets(input, INPUT_SIZE, stdin);
if ( (p = strchr(input, '\n')) != NULL) *p = '\0'; // remove '\n'
int ret = find_tokens(NR_OF_WORDS, WORD_LEN, input, array, delimiters, &number_of_words);
printf("tokens= %d ret= %d\n", number_of_words, ret);
for (int i=0; i < number_of_words; i++)
printf("%d: %s\n", i, array[i]);
printf("End\n");
return 0;
}
Test:
Insert sentence: ..........1234567,,,,,,abcdefgh....123::::::::::::
tokens= 3 ret= 1
0: 123
1: abc
2: 123
End
You are not '\0'-terminating the strings and you are scanning the source from
the beginning every time you've found a empty character.
You only need one loop and, the inner loop and the condition must be s[i] != 0:
int j = 0; // index for array
int k = 0; // index for array[j]
for(i = 0; s[i] != '\0'; ++i)
{
if(k == 99)
{
// word longer than array[j] can hold, aborting
array[j][99] = 0; // 0-terminating string
break;
}
if(j == 99)
{
// more words than array can hold, aborting
break;
}
if(s[i] == ' ')
{
array[j][k] = 0; // 0-terminating string
j++; // for the next entry in array
k = 0;
} else
array[j][k++] = s[i];
}
Note that this algorithm doesn't handle multiple spaces and punctuation marks.
This can be solved by using a variable that stores the last state.
int j = 0; // index for array
int k = 0; // index for array[j]
int sep_state = 0; // 0 normal mode, 1 separation mode
for(i = 0; s[i] != '\0'; ++i)
{
if(k == 99)
{
// word longer than array[j] can hold, aborting
array[j][99] = 0; // 0-terminating string
break;
}
if(j == 99)
{
// more words than array can hold, aborting
break;
}
// check for usual word separators
if(s[i] == ' ' || s[i] == '.' || s[i] == ',' || s[i] == ';' || s[i] == ':')
{
if(sep_state == 1)
continue; // skip multiple separators
array[j][k] = 0; // 0-terminating string
j++; // for the next entry in array
k = 0;
sep_state = 1; // enter separation mode
} else {
array[j][k++] = s[i];
sep_state = 0; // leave separation mode
}
}
As you can see, using the sep_state variable I'm able to check if multiple
separators come one after the other and skips subsequent separators. I also
check for common punctuation marks.
#include <stdio.h>
int main()
{
char s[10000]; // sentence
char array[100][100]; // array where i put every word
printf("Insert sentence: "); // receive the sentece
gets(s);
printf("%s",s);
int i = 0;
int j = 0;
int k = 0;
for(j = 0; s[j] != '\0'; j++){ // loop until i reach the end
if ( s[j] != ' ' || s[j] == '\0' )
{
array[i][k] = s[j];
k++;
}
else {
i++;
k = 0;
}
}
return 0;
}
please note that the gets function is very unsafe and shouldn't in any case be used, use scanf or fgets instead

How to exit scanf loop when there is a space

For example, the user shall put the input like that, "ABC123," but not "ABC 123" or "A BC123."
Here is my code:
unsigned int convert_to_num(char * string) {
unsigned result = 0;
char ch;
//printf("check this one %s\n", string);
while(ch =*string++) result = result * 26 + ch - 'A' + 1;
return result;
}
int main()
{
char input_string[100];
char arr_col[100] = {'\0'};
char arr_row[100] = {'\0'};
int raiseflag;
int started_w_alpha =0;
int digitflag = 0;
while(scanf("%s", &input_string) != EOF) {
int i = 0, j = 0, digarr = 0;
while (i <=5) {
if (input_string[i] == '\0') {printf("space found!");}
if ((input_string[i] >= 'A' && input_string[i] <= 'Z') && (digitflag == 0)) {
started_w_alpha = 1;
arr_col[j] = input_string[i]; j++;
}
//printf("something wrong here %s and %d and j %d\n", arr_holder, i, j);
if (started_w_alpha == 1) {
if (input_string[i] >=48 && input_string[i]<=57){ digitflag = 1; arr_row[digarr] =input_string[i]; digarr++; }
}
i++; if (i == 5) { raiseflag =1; }
}
printf(" => [%d,%s]\n", convert_to_num(arr_col), arr_row);
if (raiseflag == 1) { raiseflag = 0; memset(arr_col, 0, 5); memset(input_string, 0, 5); memset(arr_row, 0, 5); digitflag = 0; started_w_alpha = 0; }
}
return 0;
}
Apparently, \0 doesn't work in my case because I have an array of 5 and user can put 2 chars. I want to exit the loop whenever a space is found in between the characters.
This is the whole code. I added {'\0'} my array because of the extra characters I get when there is less than 5 characters.
Thanks!
Since the index is starting from 0 and input_string[5]; array size is 5, the only valid indexes are from 0 to 4.
but your loop while (i <=5) { go till 5, it is mean you exceed the array.
If you insert 5 characters to the string, the terminating null is the 6th.
Since you exceed the array it written over some other variable. but you still can find it when you check input_string[5]
So if you want to insert 5 characters you array size should be at least 6
char input_string[6];
if you want to check only the first 5 elements you'll have to change the loop to:
while (i < 5) {
and as I wrote in the comment if you find the terminating null, no use to continue the loop, since it contain garbage or leftover from the previous iteration.
Therefor you should break if it found, like this:
if (input_string[i] == '\0') {printf("space found!"); break;}
EDIT
check this program: it use fgets to read the whole input, then search for white spaces.
Note it doesn't trim the input, means it won't remove spaces when thay appear at the beginning or at the end of the input.
#include <ctype.h>
#include <string.h>
#include <stdio.h>
int main()
{
int i ,size;
char input_string[100];
fgets(input_string,100,stdin);
i=0;
size = strlen(input_string);
while (i<size-1){ //enter is also count
if (isspace(input_string[i]))
{
printf("space found!");
break;
}
i++;
}
return 0;
}
EDIT2
Now with a trim, so it will remove leading and ending spaces:
#include <ctype.h>
#include <string.h>
#include <stdio.h>
char* trim(char *input_string)
{
int i=0;
char *retVal = input_string;
i = strlen(input_string)-1;
while( i>=0 && isspace(input_string[i]) ){
input_string[i] = 0;
i--;
}
i=0;
while(*retVal && isspace(retVal[0]) ){
retVal ++;
}
return retVal;
}
int main()
{
int i ,size;
char input_string[100],*ptr;
fgets(input_string,100,stdin);
ptr = trim(input_string);
i=0;
size = strlen(ptr);
while (i<size){
if (isspace(ptr[i]))
{
printf("space found!");
break;
}
i++;
}
return 0;
}

Need help creating a FindMaxOverlap function

I'm trying to create a function that, given two C strings, it spits back the number of consecutive character overlap between the two strings.
For example,
String 1: "Today is monday."
String 2: " is monday."
The overlap here would be " is monday.", which is 11 characters (it includes the space and '.').
If you need something more efficient, consider that a partial mismatch between Strings 1 and 2 means you can jump the length of the remainder of String 2 along String 1. This means you don't need to search the entirety of String 1.
Take a look at the Boyer-Moore algorithm. Though it is used for string searching, you could implement this algorithm for finding the maximum-length substring using String 2 as your pattern and String 1 as your target text.
There is probably a more efficient way to do this, but here's a simple approach:
#include <string.h>
int main() {
char s1[17] = "Today is monday.";
char s2[12] = " is monday.";
int max = 0;
int i_max = -1;
int j_max = -1;
int i = 0, j = 0, k=0;
int endl = 0, sl1, sl2;
char *ss1, *ss2;
for(i = 0; i < strlen(s1)-1; i++) {
ss1 = s1+i;
sl1 = strlen(ss1);
if(max >= sl1) {
break; // You found it.
}
for(j = 0; j < strlen(s2)-1; j++) {
ss2 = s2+j;
sl2 = strlen(ss2);
if(max >= sl2) {
break; // Can't find a bigger overlap.
}
endl = (sl1 > sl2)?sl2:sl1;
int n_char = 0;
for(k = 0; k < endl+1; k++) {
// printf("%s\t%s\n", ss1+k, ss2+k); // Uncomment if you want to see what it compares.
if(ss1[k] != ss2[k] || ss1[k] == '\0') {
n_char = k;
break;
}
}
if(n_char > max) {
max = n_char;
i_max = i;
j_max = j;
}
}
}
char nstr[max+1];
nstr[max] = '\0';
strncpy(nstr, s1+i_max, max);
printf("Maximum overlap is %d characters, substring: %s\n", max, nstr);
return 0;
}
Update: I have fixed the bugs. This definitely compiles. Here is the result: http://codepad.org/SINhmm7f
The problems were that endl was defined wrong and I wasn't checking for end-of-line conditions.
Hopefully the code speaks for itself.
Here is my solution, it will return the position of the overlap starting point, it's a bit complex, but that's how it's done in C:
#include <string.h>
int FindOverlap (const char * a, const char * b)
{
// iterators
char * u = a;
char * v = b;
char * c = 0; // overlap iterator
char overlapee = 'b';
if (strlen(a) < strlen(b)) overlapee = 'a';
if (overlapee == 'b')
{
while (*u != '\0')
{
v = b; // reset b iterator
c = u;
while (*v != '\0')
{
if (*c != *v) break;
c++;
v++;
}
if (*v == '\0') return (u-a); // return overlap starting point
}
}
else if (overlapee == 'a')
{
while (*v != '\0')
{
u = a; // reset b iterator
c = v;
while (*u != '\0')
{
if (*c != *u) break;
c++;
u++;
}
if (*v == '\0') return (v-b); // return overlap starting point
}
}
return (-1); // not found
}

Resources