How to check if a string ends with another string in C
Since strcmp
takes an address of a const char *
, then we can pass the address of the character at position strlen(imgIn) - 3
const char *img = "some_picture.jpg";
const char *extension = img + strlen(img) - 3;
if(!strcmp(extension, "jpg"))
printf("%s", "JPG extension");
However, there is a problem. What if the extension is jpeg
, then extension
would contain peg
. In this case, one solution would be to iterate through the string backward until we hit the first .
character.
const char *get_extension(const char *img, size_t sz) {
const char *ptr;
ptr = img;
img += sz;
for(; img != ptr; --img) {
if(*img == '.')
return(img + 1);
}
return(NULL);
}
const char *img = "some_picture.jpeg";
const char *extension = get_extension(img, strlen(img));
if(extension != NULL)
/* handle valid input */
else
/* handle invalid input */
How can I check whether a string ends with .csv in C
How about:
char *dot = strrchr(str, '.');
if (dot && !strcmp(dot, ".csv"))
/* ... */
How to use pointers to figure out if a c-string ends with another c-string?
You tagged your question as C++, but your code technically suggests "C", which is fine with me.
A "C" solution
// returns true if "s2" ends with "s1"
// examples s1="World" and s2="Hello World" => returns true
// examples s1="Hello" and s2="Hello World" => returns false
bool endsWith(const char* s1, const char* s2)
{
size_t len1 = strlen(s1);
size_t len2 = strlen(s2);
// if s1 is longer than s2, then we can trivially reject it
if (len1 > len2)
{
return false;
}
size_t offset = len2 - len1;
s2 += offset;
return (strcmp(s1, s2) == 0);
}
Conversion of string.endswith method into C
Does this look like it's covering all the cases in an endswith, or am I missing some edge cases?
You are missing at least the case where the substring appears twice or more, one of the appearances at the end.
I wouldn't use strstr()
for this. Instead, I would determine from the relative lengths of the two strings where in the main string to look, and then use strcmp()
. Example:
bool endswith(char* str, char* substr) {
if (!str || !substr) return false;
size_t length_of_string = strlen(str);
size_t length_of_substring = strlen(substr);
if (length_of_substring > length_of_string) return false;
return (strcmp(str + length_of_string - length_of_substring, substr) == 0);
}
With regard to that return
statement: str + length_of_string - length_of_substring
is equivalent to &str[length_of_string - length_of_substring]
-- that is, a pointer to the first character of the trailing substring the same length the same length as substr
. The strcmp
function compares two C strings, returning an integer less than, equal to, or greater than zero depending on whether the first argument is lexicographically less than, equal to, or greater than the second. In particular, strcmp()
returns 0 when its argument are equal, and this function returns the result of exactly such a test.
is it common that writing C will require 5-10x more code than doing the same thing in python
Python is a higher-level language than C, so it is common for C code for a task to be lengthier than Python code for the same task. Also, that C blocks are explcitly delimited makes C code a little longer than Python code. I'm not sure that 5-10x is a good estimate, though, and I think that in this case you're comparing apples to oranges. The code analogous to your Python code is simply
int main(int argc, char* argv[]) {
if (endswith(argv[argc-1], ".py")) {
// ...
}
}
That C has no built-in endswith()
function is a separate matter.
How do you check if string ends with another string in Ada?
A slight simplification of Simon's answer:
function Ends_With (Source, Pattern : String) return Boolean is
begin
return Pattern'Length <= Source'Length
and then Source (Source'Last - Pattern'Length + 1 .. Source'Last) = Pattern;
end Ends_With;
How to check if string contains a substring at the end?
Your function has problems:
- you omit the return type, this is no longer supported by Standard C.
- The first
for
loop effectively erases the string pointed to bystr2
. There is no guarantee it even has a null terminator. - the
while
loop invokes undefined behavior if thestr1
does not contain a.
or if it is shorter thanstr2
. - do not hardcode ASCII values such as
97
or122
. It is neither portable not even readable. Use'a'
and'z'
or preferably the functions defined in<ctype.h>
.
Here is a simple string function for your purpose:
int str_ends_with(const char *s, const char *suffix) {
size_t slen = strlen(s);
size_t suffix_len = strlen(suffix);
return suffix_len <= slen && !strcmp(s + slen - suffix_len, suffix);
}
How does C know the end of my string?
This does not happen by magic. You have in your code:
for (i = 0; i <= strlen(line); i++)
^^
The loop index i
runs till strlen(line)
and at this index there is a nul character in the character array and this gets copied as well. As a result your end result has nul character at the desired index.
If you had
for (i = 0; i < strlen(line); i++)
^^
then you had to put the nul character manually as:
for (i = 0; i < strlen(line); i++)
{
if ( line[i] != ' ' )
{
non_spaced[j] = line[i];
j++;
}
}
// put nul character
line[j] = 0;
Check substring exists in a string in C
if (strstr(sent, word) != NULL) {
/* ... */
}
Note that strstr
returns a pointer to the start of the word in sent
if the word word
is found.
Related Topics
Wait Until User Presses Enter in C++
About the Binary Compatibility of Linux
How to Enable C++11 in Qt Creator
Comparing Arrays for Equality in C++
C++ Program Converts Fahrenheit to Celsius
Efficient Way to Determine Number of Digits in an Integer
Does "Const" Just Mean Read-Only or Something More
Difference Between Pointer and Reference as Thread Parameter
Is Auto as a Parameter in a Regular Function a Gcc 4.9 Extension
How to an Share Address Mapping Between Two Unrelated Processes on Linux
Openprocess/Readprocessmemory/Writeprocessmemory/Closehandle Equivalent
Getting Mangled Name from Demangled Name
Is Std::Cout Guaranteed to Be Initialized
How to Compile Qt 5 Under Windows or Linux, 32 or 64 Bit, Static or Dynamic on Visual Studio or G++
Extending the C++ Standard Library by Inheritance
Differencebetween Pre-Increment and Post-Increment in the Cycle (For/While)