Delete a char in string? - c

I tried searching for it on google and could not find a simple answer, most of the questions were asking to delete all occurrences of that char from the string and what not.
My pseudo code:
for (e=0;e<length of string;e++){
if (string[e] is not a number/alphabet){
#delete it
}
}
Is there a simple built in way of doing this?
Also another question, I need to do if not isalnum(string[e]), how would I go about doing so?
is it if !(isalnum(string[e])) or is it if (isalnum(string[e]))!=0?

Typically you would build up a second array and copy the valid symbols to that one.
Deleting numbers inside arrays is only possible if you move all trailing numbers down one step, which is very inefficient. If you need a container class where you can easily delete and add items in the middle, you should be using a linked list.
You can treat the return value of isalnum as bool type. Thus either
if ( !isalnum(string[e]) )
or
if ( isalnum(string[e]) !=0 )
are fine and completely equivalent.

You can filter out characters from a string in-place by keeping two indices. That works, because the string can only get shorter and the new string will fit into the old memory. Here's how with two pointers:
int str_alnum(char *str)
{
char *p, *q;
p = q = str;
while (*p) {
if (isalnum(*p)) *q++ = *p;
p++;
}
*q = '\0';
return q - str;
}
p walks the original string, q walks the new string, possibly trailing after p. q - str is the length of the new string, which might be handy as return value.
Note that you have to pass a string that can be modified, i.e. a char array, not a constant string literal.

This is one way to do it if you are using ASCII formatted characters.
char a[256]; // Some string
char destination[256];
char * pos = destination;
for(unigned int i=0;i>strlen(a)-1;++i)
{
if(((a[i]>='A'&& a[i]<='Z') || (a[i]>='a'&& a[i]<='z') || (a[i]>='1'&& a[i]<='9')))
*pos = a[i]; //replaces letter with a whitespace
++pos;
}
*pos = '\0';
Basically what it does it it converts the letter to the corrosponding intenger and then it checks its within the range that represents the letters between A-Z, a-z and 1-9.

Related

Comparing user input from strings

I am trying to make a simple game similar to the now popular game Wordle, but I am having trouble comparing a user inputted string to that of a pre-existing string. I want to be able to compare the strings as a whole as well as each individual letter in the input and the answer. Here is the code i am working with:
#include <stdio.h>
#include <string.h>
int main()
{
char guess[5];
char answer[5] = "money";
printf("what is your first guess? ");
scanf("%s",&guess);
if (strcmp(guess,answer) == 0){
printf("\nyour guess was correct");
}
else{
printf("Your guess was incorrect");
}
return 0;
}
The user may input significantly more characters than 5-1=4.
Also, use fgets(), not scanf().
char guess[100];
fgets( guess, sizeof(guess), stdin );
Don’t forget to remove the Enter key from the user’s input:
char * p = strchr( guess, '\n' );
if (p) *p = '\0';
When storing constant character arrays, declare it with a pointer:
const char * answer = "money";
If you have a fixed list of answers, use the const array.
When storing mutable character arrays, declare it either with a large space (for future use):
char answer[100] = "money";
or let the compiler declare the exact number of elements you need:
char answer[] = "money";
I presume you will want to randomly select an answer for the user to guess at some point, so the 100-element array is a better choice. Use this if you wish to have a file of answers to use at some point.
You will probably want to normalize the user’s input in some way as well. For example, if all your answers are lowercase, you should transform user input to lowercase before comparing.
#include <ctype.h>
char * stolower( char * s )
{
for (char * p = s; *p; ++p)
*p = tolower( *p );
return s;
}
if (strcmp(tolower(guess),answer) == 0){
C strings like "money" contains 6 chars, with an extra '\0' to mark the end of a string. Which means, when stored with a char array, you'll always need an extra space for '\0' in order to use the char array as a string.
For example, strcmp for char str[10] = "aaa\0bbb" and char[4] = "aaa" will be 0 (equal), because the program will see '\0' as the end of a string, ignoring the extra chars. (btw, the way "aaa" stored in the char array is like this: ['a', 'a', 'a', '\0'])

Linear search vs strlen

In one of my assignments, I was required to use linear search to find the last char of a string and set it to a pointer, it is just a simple string eg "blah blah blah". To do this I used
int length = strlen(string);
to find the length, then used a for loop
for (i=1;i<length;i++){
if (string[i]==0){;
end_pointer = &string[i-1];
}
Is there any difference between using linear search for 0 to set the pointer as opposed to using length:
end_pointer = &string[length-1];
I think what your professor is really looking for is:
int i = 0;
while( '\0' != string[i] ) i++;
for the search
Assign after the looping has completed for best efficiency:
char * end_pointer = &string[i - 1];
I think I need to explain how strings are stored in C.
Since strings can, in general, have arbitrary length, there needs to be a way to represent that length along with the content of the string. The two most trivial ways of representing the length are as follows.
explicitly keep track of length
use a special token to denote the end of string
The C language went with the second option. Specifically, '\0' is used to denote the end of the string. So if you have a char * p, then that is a pointer† that points to the first character; the second character in the string is p[1] == *(p+1), and so on.
So how do you get the length of the string? In the first method of representing strings (NOT the C way), it's already explicitly available. With C strings, you have to start at the beginning and count how many characters there are until the special token ('\0' in C). This is called a linear search for the end of string token.
strlen implements such a linear search, but it sounds like you are not supposed to use it. Regardless, strlen doesn't actually give you the pointer to the end of the string; you would have to compute it as
char *endPtr = string + strlen(string);
In this case, endPtr will actually point to the null-termination character, which is just past the end of the string. This is a common paradigm in C for specifying ranges: the start of the range (string in this case) is usually inclusive, and the end of the range (endPtr in this case) is usually exclusive.
†
char * could just be a pointer to a single char and not necessarily a string, but that doesn't concern us here.
The difference between using a linear search for '\0' to set the pointer as opposed to using length derived from strlen() is a slight potential efficiency change.
If one rolls their own code or uses the standard library function strlen(), it is still the same order of complexity O(n). If anything, srtrlen() has potential of being more efficient.
If the goal is to create you own code and point to the last char in a string (not the '\0'), handle "" as a special case, otherwise perform a simple loop;
char *LastCharPointer(char *string) {
if (*string == '\0') {
return NULL;
}
do {
string++;
} while (*string);
return string - 1;
}
If the goal is to point to the null chanracter '\0':
char *NullCharPointer(char *string) {
while (*string) string++;
return string;
}
I am assuming the code you pasted above is not the actual code you wrote, it would be :
for( i = 0; i < strlen( string ); i++ ) {
if( string[ i ] ){
end_pointer = &string[i - 1];
}
}
You can do this in two ways :
char * end_pointer = &string[ strlen( string ) - 1 ]
or
for( i = 0; string[ i ] ; i++ );
char * end_pointer = &string[ i - 1 ]
Effectively when you call strlen( ), it runs in linear time to calculate the length. Once you have the length you can index into the string directly or, you could yourself search for the terminating '\0' character. All this works assuming that your string is null-terminated.
EDIT : The second option had a missing ";".

Tokenize Strings using Pointers in ANSI C

This is in Ansi C. I am given a string. I am supposed to create a method that returns an array of character pointers that point to the beginning of each word of said string. I am not allowed to use Malloc, but instead told that the maximum length of input will be 80.
Also, before anyone flames me for not searching the forum, I can't use strtok :(
char input[80] = "hello world, please tokenize this string"
and the output of the method should have 6 elements;
output[0] points to the "h",
output[1] points to the "w",
and so on.
How should I write the method?
Also, I need a similar method to handle input from a file with maximum of 110 lines.
Pseudocode:
boolean isInWord = false
while (*ptr != NUL character) {
if (!isInWord and isWordCharacter(*ptr)) {
isInWord = true
save ptr
} else if (isInWord and !isWordCharacter(*ptr)) {
isInWord = false
}
increment ptr
}
isWordCharacter checks whether the character is part of the word or not. Depending on your definition, it can be only alphabet character (recognize part-time as 2 words), or it may include - (recognize part-time as one word).
Because it's homework here's a part of what you might need:
char* readPtr = input;
char* wordPtr = input;
int wordCount = 0;
while (*readPtr++ != ' ');
/* Here we have a word from wordPtr to readPtr-1 */
output[wordCount++] = /* something... :) */
You'll need that in a loop, and must consider how to move onto the next word, and check for end of input.

comparing strings (from other indices rather than 0)

How can one compare a string from the middle (or some other point but not the start) to another string?
like i have a string
str1[]="I am genius";
now if i want to find a word in it how should i compare it with the word? for example the word is am.
Here is what i did.Its a bit stupid but works perfectly :D
#include<stdio.h>
#include<string.h>
void print( char string[]);
int main()
{
int i;
char string1[20];
printf("Enter a string:");
gets(string1);
print(string1);
return 0;
getch();
}
void print(char string[])
{
int i,word=1,sum=0,x;
for(i=0; ;i++)
{
sum++;
if(string[i]==' ')
{
printf("Word#%d:%d\n",word,sum-1);
sum=0;
word++;
}/* if ends */
if(string[i]=='\0')
{ // program sai kaam karnay k liye ye code yahan bhi paste hona chahyey
printf("Word#%d:%d\n",word,sum-1);
sum=0;
word++;
break;
}
}/* for ends*/
}
Use strncmp():
strncmp( whereToFind + offsetToStartAt, patternToFind, patternLength );
If you wish to find a substring in a string, use the function strstr():
char *p = strstr(str1, "am");
if (p != NULL)
{
// p now points to start of substring
printf("found substring\n");
}
else
{
printf("substring not found\n");
}
If you want to compare the remainder of string s1 starting at index i1 to the remainder of string s2 starting at i2, it's very easy:
result = strcmp(s1+i1, s2+i2);
If you want to see if the substring of s1 beginning at i1 matches the string s2, try:
result = strcmp(s1+i1, s2);
or:
result = strncmp(s1+i1, s2, strlen(s2));
depending on whether you want the whole remainder of s1 to match or just the portion equal in length to s2 to match (i.e whether s1 contains s2 as a substring beginning at position i1.
If you want to search for a substring, use strstr.
Since this is homework I am assuming you can't use standard functions, so I can think of two solutions:
Split all of the words into a link
list, then just compare each string
until you find your word.
Just use a for loop, start at the
beginning, and you can use [] to
help jump through the string, so
instr[3] would be the fourth
character, as the index is
zero-based. Then you just see if you are at your word yet.
There are optimizations you can do with (2), but I am not trying to do your homework for you. :)
One option you be to use
size_t strspn( char *s1, const char *s2) /* from #include <string.h> */
*returns the length of the longest substring of s1 that begins at the start of s1 and consists only of the characters found in s2.
If it returns ZERO than there is no substring.
You can use parse the string into words and store them in new char arrays/pointers.
Or
Suppose the string you want to find is "am" stored in ptr *str2.
You start comparison using the index[] from str1 till you find a matching char for index 0 from str2
Once you find a match increment both pointers till you reach end of str2 to compare entire string.
If there is no match then continue to find char at index 0 in str2 in str1 from the place where you entered step 2.
Alternatively
You have to use a two dimensinal array.
char str[3][10] = { "i","am","2-darray"};
Here str[1] will contain "am". Thats assuming you want to get indvidual words of a string.
Edit: Removed the point diverting from OP

Parse a String in C

Using just C
I would like to parse a string and:
count the occurrences of a character in a string (for example, count all the 'e's in a passed in string)
Once counted (or even as I am counting) replace the e's with 3's
OK, you're either lazy, or stuck, assuming stuck.
You need a function with a signature something like
int ReplaceCharInString(char* string, char charToFind, char charThatReplaces)
{
}
Inside the function you need
To declare an integer to count the
occurrences
A loop that moves from the start of
the string to it's end
inside the loop, an if statement to
check is the current char the
charToFind,
statements to increment the count of
occurrences and perform the
replacement
After the loop, you need to return
the count of occurrences
This function will take a string, replace every 'e' with '3', and return the number of times it performed the substitution. It's safe, it's clean, it's fast.
int e_to_three(char *s)
{
char *p;
int count = 0;
for (p = s; *p; ++p) {
if (*p == 'e') {
*p = '3';
count++;
}
}
return count;
}
Here's a shell to get you started. Ask here if you need any help.
#include <string.h>
#include <stdio.h>
int main(){
const char* string = "hello world";
char buffer[256];
int e_count = 0;
char* walker;
// Copy the string into a workable buffer
strcpy(buffer,string);
// Do the operations
for(walker=buffer;*walker;++walker){
// Use *walker to read and write the current character
}
// Print it out
printf("String was %s\nNew string is %s\nThere were %d e's\n",string,buffer,e_count);
}
In general, it's better use a standard library function rather than rolling your own. And, as it just so happens, there is a standard library function that searches a string for a character and returns a pointer to it. (It deals with a string, so look among the functions that have the prefix "str") (The library function will almost certainly be optimized to use specialized CPU opcodes for the task, that hand written code would not)
Set a temp pointer (say "ptr") to the start of the string.
In a loop, call the function above using ptr as the parameter, and setting it to the return value.
Increment a counter.
Set the character at the pointer to "3" break when 'e' is not found.
Some of you guys are starting in the middle.
A better start would be
char *string = "hello world";
Assert(ReplaceCharInString(string, 'e', '3') == 1);
Assert(strcmp(string, "h3llo world") == 0);

Resources