From: Chig
By null terminated, do you mean what if the string does not contain the '\0' at the end? In which case, I say they all do.
That is what he means. Basically in Cpp, all strings should be null terminated. Meaning that as soon as an iterator hits the '\0', we know that that was the end of the string. There are other types of strings that are double null terminated but both of these are inheritted from C.
C doesn't contain the stl library and so the standard is to ensure all strings are null terminated and to use fgets for getting input rather than scanf. Scanf isn't buffer overflow protected that's why.
So with all that said, if you were to attempt to get a string with spaces, scanf will give you trouble unless of course you know regexes and you do: "scanf("%[^\n]s", Variable)". This is because scanf stands for scan formatted and that's exactly what it does (__format(##X)__). Something like that. It's some awkward preprocessor define. It has no regard for special characters or anything else.
fgets will continue to grab characters until the enter key is pressed and it's MUCH safer. BUT beware that fgets will also include that newline from the enter key into your string so it is your job to remove it after grabbing input but setting it null! If a user enters too many characters with fgets, it will throw. With Scanf, it will keep allowing it and cause you a TON of problems. Remember what I told you in the last post about malloc to prevent and realloc?
With all that said, let us assume that you take these risks because you cannot use C++ STL and guarantee me that those strings are null terminated then:
#include <cstdio>
#include <cstdlib>
int count(char c[])
{
int i = 0;
for (int n = 0; c[n]!='\0'; n++)
{
i++;
}
return i;
}
bool compare(char w1[], char w2[])
{
for (int w = 0; w1[w] != '\0'; w++)
{
if (w1[w] == w2[w])
{
if ((w1[w] == '\0') && (w2[w] == '\0') && (count(w1)== count (w2)))
{
return true;
}
}
else
{
return false;
}
}
return true;
}
int FindSearch(char SearchString[], char WhatToSearch[])
{
char SS[200];
char WS[200];
int Count = count(WhatToSearch);
for(int b = 0; SearchString[b] != '\0'; b++)
{
if (SearchString[b] == WhatToSearch[0]) //So you are checking if the first letter of the search string is in the larger string. Correct!
{
for(int v = 0; v < Count; v++) //No need for v - 1. You are searching for your entire string in the larger from the starting point of C.
{
WS[v] = SearchString[b + v]; //You want to create a substring starting from b until the length of v from the larger string.
if (v == Count - 1) //If we are at the end of the string..
{
WS[Count + 1] = '\0'; //Null terminate the string.
if (compare(WS, WhatToSearch)) //Compare our constructed string with the one we are trying to find.
return b; //If the two strings did match, return the position it was found at.
}
}
}
}
return -1;
}
int main()
{
char T[200];
char L[200];
printf("Write a string\n");
fgets(T, sizeof(T), stdin);
T[count(T) - 1] = '\0'; //Removes the newline.
printf("\nWhat sub-string do you want to look for within %s? \n", T);
fgets(L, sizeof(T), stdin);
L[count(L) - 1] = '\0'; //Removes the newline.
if ((FindSearch(T, L)) >= 0)
{
printf("\nThe sub-string occurs at location %i", (FindSearch(T, L)));
printf("\n");
}
else
{
printf("The sub-string %s is not located within the string %s\n", L, T);
}
return EXIT_SUCCESS;
}
The difference is that you aren't constructing your strings right. Also you MUST terminate them with the null character! Do not forget this.
Now I know you make ask why does it only get the first occurance if any. Well that's because we return the position as soon as it's found. If you want all occurances, you must make an array of integers, set all values to -1. For every position the string is found, set that position to the correct value. Return the array and print every position that is not -1.