I'm trying to check if a character belongs to a list/array of invalid characters.
Coming from a Python background, I used to be able to just say :
for c in string:
if c in invalid_characters:
#do stuff, etc
How can I do this with regular C char arrays?
The less well-known but extremely useful (and standard since C89 — meaning 'forever') functions in the C library provide the information in a single call. Actually, there are multiple functions — an embarrassment of riches. The relevant ones for this are:
7.21.5.3 The strcspn function
Synopsis
#include <string.h>
size_t strcspn(const char *s1, const char *s2);
Description
The strcspn function computes the length of the maximum initial segment of the string
pointed to by s1 which consists entirely of characters not from the string pointed to by
s2.
Returns
The strcspn function returns the length of the segment.
7.21.5.4 The strpbrk function
Synopsis
#include <string.h>
char *strpbrk(const char *s1, const char *s2);
Description
The strpbrk function locates the first occurrence in the string pointed to by s1 of any
character from the string pointed to by s2.
Returns
The strpbrk function returns a pointer to the character, or a null pointer if no character
from s2 occurs in s1.
The question asks about 'for each char in string ... if it is in list of invalid chars'.
With these functions, you can write:
size_t len = strlen(test);
size_t spn = strcspn(test, "invald");
if (spn != len) { ...there's a problem... }
Or:
if (strpbrk(test, "invald") != 0) { ...there's a problem... }
Which is better depends on what else you want to do. There is also the related strspn() function which is sometimes useful (whitelist instead of blacklist).
The equivalent C code looks like this:
#include <stdio.h>
#include <string.h>
// This code outputs: h is in "This is my test string"
int main(int argc, char* argv[])
{
const char *invalid_characters = "hz";
char *mystring = "This is my test string";
char *c = mystring;
while (*c)
{
if (strchr(invalid_characters, *c))
{
printf("%c is in \"%s\"\n", *c, mystring);
}
c++;
}
return 0;
}
Note that invalid_characters is a C string, ie. a null-terminated char array.
Assuming your input is a standard null-terminated C string, you want to use strchr:
#include <string.h>
char* foo = "abcdefghijkl";
if (strchr(foo, 'a') != NULL)
{
// do stuff
}
If on the other hand your array is not null-terminated (i.e. just raw data), you'll need to use memchr and provide a size:
#include <string.h>
char foo[] = { 'a', 'b', 'c', 'd', 'e' }; // note last element isn't '\0'
if (memchr(foo, 'a', sizeof(foo)))
{
// do stuff
}
use strchr function when dealing with C strings.
const char * strchr ( const char * str, int character );
Here is an example of what you want to do.
/* strchr example */
#include <stdio.h>
#include <string.h>
int main ()
{
char invalids[] = ".#<>#";
char * pch;
pch=strchr(invalids,'s');//is s an invalid character?
if (pch!=NULL)
{
printf ("Invalid character");
}
else
{
printf("Valid character");
}
return 0;
}
Use memchr when dealing with memory blocks (as not null terminated arrays)
const void * memchr ( const void * ptr, int value, size_t num );
/* memchr example */
#include <stdio.h>
#include <string.h>
int main ()
{
char * pch;
char invalids[] = "#<>#";
pch = (char*) memchr (invalids, 'p', strlen(invalids));
if (pch!=NULL)
printf (p is an invalid character);
else
printf ("p valid character.\n");
return 0;
}
http://www.cplusplus.com/reference/clibrary/cstring/memchr/
http://www.cplusplus.com/reference/clibrary/cstring/strchr/
You want
strchr (const char *s, int c)
If the character c is in the string s it returns a pointer to the location in s. Otherwise it returns NULL. So just use your list of invalid characters as the string.
strchr for searching a char from start (strrchr from the end):
char str[] = "This is a sample string";
if (strchr(str, 'h') != NULL) {
/* h is in str */
}
I believe the original question said:
a character belongs to a list/array of
invalid characters
and not:
belongs to a null-terminated string
which, if it did, then strchr would indeed be the most suitable answer. If, however, there is no null termination to an array of chars or if the chars are in a list structure, then you will need to either create a null-terminated string and use strchr or manually iterate over the elements in the collection, checking each in turn. If the collection is small, then a linear search will be fine. A large collection may need a more suitable structure to improve the search times - a sorted array or a balanced binary tree for example.
Pick whatever works best for you situation.
Related
Is it possible to use one string function inside another string function. See below....
strcmp(string1, strupr(string2));
Here I have used strupr() function to make the all characters of string2 in uppercase then It will use to compare with string1 by strcmp() function.
Below is my program...
#include <stdio.h>
#include <string.h>
int main()
{
char str[41], name[43];
gets(str);
gets(name);
if (strcmp(strupr(str), name) == 0)
printf("\nwow it works.");
return 0;
}
Following is the error shown by compilor..
use of undeclared identifier 'strupr'; did you mean 'strdup'?
To condense the comments into an answer:
As long as the return type of the inner function matches (or is compatible with) the argument type of the outer function, this will work.
A simple example, which will print the number 3.
int add1(int a) {
return a + 1;
}
int main(void) {
printf("%d\n", add1(add1(add1(0))));
}
So as long as your strupr function returns a char * (or const char *, etc.) it will work as the function prototype for strcmp is:
int strcmp(const char *s1, const char *s2);
To create a basic function to uppercase an entire string, you simply loop through the string character by character and use the toupper function on each character. There are several ways to implement this loop.
Here is one such way:
char *upcase(char *s) {
for (char *p = s; p && *p; p++)
*p = toupper(*p);
return s;
}
Note that this is a destructive function, which alters the contents of the string passed to it. It will not work with static strings (e.g., const char *foo = "abcdefg";).
Since your aim seems to compare the two strings in a case insensitive fashion, you should use stricmp:
if (stricmp(str, name) == 0)
printf("\nwow it works.");
It has the additional benefits of not either changing your original string or allocating a new string you will have to free().
I want to create a function called remstr(). This function removes a given string from another string without using string.h. Example:
str1[30]= "go over stackover"
str2[20]= "ver"
strrem[20]= "go o stacko"
Please help me
C gives you lots of useful building blocks for doing this. In particular, you can build this function using three standard library functions: strstr (to find the string you want to remove), strlen to compute the length of the rest of the string, and memcpy to copy the parts you don't want to delete into the destination (you'll need to use memmove instead of memcpy if you want the function to operate in place). All three functions are declared in <string.h>.
Take a crack at writing the function, and ask specific questions if and when you run into trouble.
The pseudo code is pretty straight forward for what you want to do, and if you can't use string.h functions then you just have to recreate them.
char * remstr(char *str1, char * str2)
{
get length of str1
get length of str2
for(count from 0 to length of str2 - length of str1) {
if ( str1[count] != str2[count])
store str2[count] in to your new string
else
loop for the length of str1 to see if all character match
hold on to them in case they don't and you need to add them into you
new string
}
return your new string
}
You need to figure out the details, does remstr() allocate memory for the new string? Does it take an existing string and update it? What is the sentinel character of your strings?
You'll need a strlen() for this to work, since you can't use it you need to make something like:
int mystrlen(char* str) {
while not at the sentinel character
increment count
return count
}
#include <stdio.h>
#include <stdlib.h>
void remstr(char *str1, char *str2, char *strrem)
{
char *p1, *p2;
if (!*str2) return;
do {
p2 = str2;
p1 = str1;
while (*p1 && *p2 && *p1==*p2) {
p1++;
p2++;
}
if (!(*p2)) str1 = p1-1;
else *strrem++ = *str1;
} while(*str1 && *(++str1));
*strrem = '\0';
}
int main() {
char str1[30]= "go over stackover";
char str2[20]= "ver";
char strrem[30];
remstr(str1, str2, strrem);
printf("%s\n",strrem);
}
with this function you can even put the result in the same string buffer str1:
remstr(str1, str2, str1);
printf("%s\n",str1);
I want to know about strchr function in C++.
For example:
realm=strchr(name,'#');
What is the meaning for this line?
From here.
Returns a pointer to the first occurrence of character in the C string str.
The terminating null-character is considered part of the C string. Therefore, it can also be located to retrieve a pointer to the end of a string.
/* strchr example */
#include <stdio.h>
#include <string.h>
int main ()
{
char str[] = "This is a sample string";
char * pch;
printf ("Looking for the 's' character in \"%s\"...\n",str);
pch=strchr(str,'s');
while (pch!=NULL)
{
printf ("found at %d\n",pch-str+1);
pch=strchr(pch+1,'s');
}
return 0;
}
will produce output
Looking for the 's' character in "This is a sample string"...
found at 4
found at 7
found at 11
found at 18
www.cplusplus.com is a very usable site for C++ help. Such as explaining functions.
For strchr:
Locate first occurrence of character in string Returns a pointer to
the first occurrence of character in the C string str.
The terminating null-character is considered part of the C string.
Therefore, it can also be located to retrieve a pointer to the end of
a string.
char* name = "hi#hello.com";
char* realm = strchr(name,'#');
//realm will point to "#hello.com"
Just for those who are looking here for source code/implementation:
char *strchr(const char *s, int c)
{
while (*s != (char)c)
if (!*s++)
return 0;
return (char *)s;
}
(origin: http://clc-wiki.net/wiki/strchr)
Is there any method in C can find a text within another text?
For example, text = "abaHello", textneedtoSearch = "Hello";.
If the text contains "Hello", return true, else return false.
Use strstr, see http://pubs.opengroup.org/onlinepubs/9699919799/functions/strstr.html
Character and string searching functions
`char *strstr( const char *s1, const char *s2)`
returns a pointer to the first
instance of string s2 in s1. Returns
a NULL pointer if s2 is not
encountered in s1.
In additon,
int strcmp(const char *s1, const char *s2);
strcmp compares the string s1 to the string s2. The function returns 0 if they are the same, a number < 0 if s1 < s2, a number > 0 if s1 > s2.
This is one of the most commonly used
of the string-handling functions.
And check this link for anything about string functions in C, C string functions
if (strstr(text, textneedtoSearch) != NULL)
printf("found\n");
You can find a text on string file:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main(int argc, char **argv)
{
FILE *fp=fopen(argv[1],"r");
char tmp[256]={0x0};
while(fp!=NULL && fgets(tmp, sizeof(tmp),fp)!=NULL)
{
if (strstr(tmp, argv[2]))
printf("%s", tmp);
}
if(fp!=NULL) fclose(fp);
return 0;
}
The C function strstr returns a pointer to the start of the word you were looking for if it is contained in the text you were searching in, or NULL, if it does not contain the word you are looking for.
Syntax:
char *p = strstr(wheretolook,whattolookfor);
I tried to code a function which replace all string s1 to s2, in a given string s.
however, i don't know why my program stop at the line *p=0 in that replace function without any error reported? ##
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void replace(char * s, char * s1, char * s2) {
char * p; int l=strlen(s2);
while ((p=strstr(s,s1))) {
*p=0;
p+=l;
strcat(s,s2);
strcat(s,p);
}
}
int main(void) {
char *s=(char *)"cmd=ls+-la&abc=xyz";
replace (s, "+", " ");
printf("%s", s);
return EXIT_SUCCESS;
}
There are some problems with the replace function but, first of all, there is a big difference between a pointer to a constant char array vs a character array:
char *str = "some string";
Assigns str the address of the immutable character array (read-only), it does not copy the string, only pointers are involved. Any attempt to modify that string will result in undefined behavior.
char str[] = "some string";
In this case str is an array (of size big enough to hold the string + \0) that is initialized to that string, allowing the modification of individual characters within the array.
Back to your replace function.
I will start with the first thing that I saw which is your use of strstr and strcat inside the loop is highly inefficient. Every time you call strstr it starts from the beginning of the string and searches for the first occurrence of the second string all over, the same problem can be seen with strcat which needs to find the null-terminator every time.
Another issue I see is if the replacement string (s2) is longer than the original string (s1) you must shift the entire string to accommodate for the additional characters of the new string. The same issue will occur if the replacement string is shorter.
a basic method to replace a simple char might look like this:
while (*s)
{
if (*s == c1)
*s = c2;
++s;
}
a little more complex method to replace a string would be:
/* PRECONDITION: strlen(s1) == strlen(s2) */
int l = strlen(s2);
while (*s)
{
if (!strncmp(s, s1, l))
{
memcpy(s, s2, l);
s += l;
}
else
++s;
}
Your compiler is allowed to place string literals into read-only memory, which is probably what it did with s.
Try:
char s[] = "cmd=ls+-la&abc=xyz";
This changes s from a pointer to a string literal into an array initialized with your string.