void getAvailableLetters(char lettersGuessed[], char availableLetters[])
is function that I need to create. It must use strings.
availableLetters are letters of alphabet
lettersGuessed are letters inserted by user
function is supposed to do this:
Available letters: abcdefghijklmnopqrstuvwxyz
Gimme a letter: (let's guess 'm')
Available letters: abcdefghijklnopqrstuvwxyz //all without letter m
Gimme a letter: (let's hess 'b')
Available letters: acdefghijklnopqrstuvwxyz //all without letters m & b
Any algorythms, advices, codes or smth what would help me to do it would be great.
Test this one out. The function char_replace() takes in the source string, the character to find and the string to replace the character (can be also one char). In your case, you pass "" (empty value) for the char to be replaced with, because you want to remove it. But the parameter might come in handy, so I included it.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *char_replace(char *, char, char *);
int main(void) {
char input[4096] = "abcdefghijklmnopqrstuvwxyz";
char *signature = char_replace(input, 'a', "");
printf("%s\n", input);
return 0;
}
char *char_replace(char *str, char find, char *replace) {
char *ret=str;
char *wk, *s;
// string duplication
wk = s = strdup(str);
while (*s != 0) {
if (*s == find){
while(*replace)
*str++ = *replace++;
++s;
} else
*str++ = *s++;
}
*str = '\0';
free(wk);
// returning the result string
return ret;
}
This approach is counting on the input array of chars (string) to have enough space with 4096 allocated to it.
#include<stdio.h>
#include<string.h>
char availableLetters[27]={"abcdefghijklmnopqrstuvwxyz"},lettersGuessed[2];
void getAvailableLetters(char lettersGuessed[], char availableLetters[])
{
int i,flag=0;
for(i=0;availableLetters[i]!='\0';i++)
{
if(availableLetters[i]==lettersGuessed[0])
{
flag=1;
for(;availableLetters[i]!='\0';i++)
{
availableLetters[i]=availableLetters[i+1];
}
}
if(flag==1)
{
availableLetters[i-1]='\0';
break;
}
}
}
input()
{
printf("Gimme a letter:");
scanf("%c",&lettersGuessed[0]);
fflush(stdin); //deleting extra characters
lettersGuessed[1]='\0';
}
output()
{
printf("Available letters:");
puts(availableLetters);
}
main()
{
output();
input();
getAvailableLetters(lettersGuessed,availableLetters);
output();
input();
getAvailableLetters(lettersGuessed,availableLetters);
output();
}
Related
I need ideas for a recursive code that deletes a specific char in a string, and move all the other sting chars together
for Example :
"the weather is cloudy"
the entered char is 'e':
result :
"th wathr is cloudy"
I really don't have any idea how to start, thanks for the help.
#include <stdio.h>
void remove_impl(char* s, char c, char* d) {
if (*s != c) {
*d++ = *s;
}
if (*s != '\0') {
remove_impl(++s, c, d);
}
}
void remove(char* s, char c) {
remove_impl(s, c, s);
}
int main() {
char s[] = "the weather is cloudy";
remove(s, 'e');
puts(s);
}
How it works? Consider remove_impl. s is the original string, c is the character to be deleted from s, d is the resulting string, into which the characters of s, not equal to c, are written. Recursively iterates through the characters of s. If the next character is not equal to c, then it is written in d. The recursion stop point is the condition of checking that the end of s is reached. Since it is necessary to modify the source string, the wrapper is implemented (remove) in which as d, the original string (s) is passed.
An easy way to do it is to loop over the string and add any letter that doesn't match the unwanted letter.
Here's a demonstration:
char *source = "the weather is cloudy";
int source_len = strlen(source);
char *target = (char *)calloc(source_len, sizeof(char));
int target_len = 0;
char to_remove = 'e';
for(int i = 0; i < source_len; i++)
{
if(source[i] != to_remove)
{
target[target_len++] = source[i];
}
}
puts(target); // Output "th wathr is cloudy" in the console
My turn to make a proposal ! I add a assert test and use existing functions (strchr and strcpy).
#include <string.h>
#include <stdio.h>
#include <assert.h>
int removeChar(char *str, char chr)
{
assert(str != 0); // Always control entry !
char *str_pnt = strchr(str, chr);
if (str_pnt) {
strcpy(str_pnt, str_pnt+1);
removeChar(str_pnt, chr);
}
}
void main (void)
{
char str[] = "the weather is cloudy";
char char_to_delete = 'e';
removeChar(str, char_to_delete);
puts(str);
}
This can be done in many ways. What i am thinking right now is store not Allowed char array which going to filter which char should show or not. Something like following..
#include <stdio.h>
#include <string.h>
// Global Scope variable declaration
int notAllowedChar[128] = {0}; // 0 for allowed , 1 for not allowed
char inputString[100];
void recursion(int pos, int len) {
if( pos >= len ) {
printf("\n"); // new line
return;
}
if( notAllowedChar[inputString[pos]]) {// not printing
recursion( pos + 1 , len );
}
else {
printf("%c", inputString[pos]);
recursion( pos + 1 , len );
}
}
int main() {
gets(inputString); // taking input String
printf("Enter not allowed chars:: "); // here we can even run a loop for all of them
char notAllowed;
scanf("%c", ¬Allowed);
notAllowedChar[notAllowed] = 1;
int len = strlen(inputString);
recursion( 0 , len );
}
How this work
Lets say we have a simple string "Hello world"
and we want l should be removed from final string, so final output will be "Heo word"
Here "Hello world" length is 11 chars
before calling recursion function we make sure 'l' index which is 108 ascii values link 1 in notAllowedChar array.
now we are calling recursion method with ( 0 , 11 ) value , In recursion method we are having mainly 2 logical if operation, first one is for base case where we will terminate our recursion call when pos is equal or more than 11. and if its not true , we will do the second logical operation if current char is printable or not. This is simply just checking where this char is in notAllowedChar list or not. Every time we increase pos value + 1 and doing a recursion call, and finally when pos is equal or more than 11 , which means we have taken all our decision about printing char or not our recursion will terminate. I tried assign variable with meaningful name. If you still not understand how this work you should go with simple recursion simulation basic ( search in youtube ) and also you should try to manually debug how value is changing in recursion local scope. This may take time but it will be worthy to understand. All the very best.
#include <stdio.h>
/**
* Returns the number of removed chars.
* Base case: if the current char is the null char (end of the string)
* If the char should be deleted return 1 + no of chars removed in the remaining string.
* If it's a some other char simply return the number of chars removed in the remaining string
*/
int removeCAfterwardsAndCount(char* s,char c){
if((*s) == '\0'){
return 0;
}
if((*s) == c){
int noOfChars = removeCAfterwardsAndCount(s+1,c);// s+1 means the remaining string
s[noOfChars] = *s; // move the current char (*s) noOfChars locations ahead
return noOfChars +1; // means this char is removed... some other char should be copied here...
}
else{
int noOfChars = removeCAfterwardsAndCount(s+1,c);
s[noOfChars ] = *s;
return noOfChars ; // means this char is intact ...
}
}
int main()
{
char s[] = "Arifullah Jan";
printf("\n%s",s);
int totalRemoved = removeCAfterwardsAndCount(s,'a');
char *newS = &s[totalRemoved]; // the start of the string should now be originalPointer + total Number of chars removed
printf("\n%s",newS);
return 0;
}
Test Code Here
To avoid moving the chars using loops. I am just moving the chars forward which creates empty space in the start of the string. newS pointer is just a new pointer of the same string to eliminate the empty/garbage string.
#include <stdio.h>
void RemoveChar(char* str, char chr) {
char *str_old = str;
char *str_new = str;
while (*str_old)
{
*str_new = *str_old++;
str_new += (*str_new != chr);
}
*str_new = '\0'; }
int main() {
char string[] = "the weather is cloudy";
RemoveChar(string, 'e');
printf("'%s'\n", string);
return 0; }
#include <stdio.h>
#include <string.h>
char *remove_char(char *str, int c)
{
char *pos;
char *wrk = str;
while((pos = strchr(wrk, c)))
{
strcpy(pos, pos + 1);
wrk = pos;
}
return str;
}
int main()
{
char str[] = "Hello World";
printf(remove_char(str, 'l'));
return 0;
}
Or faster but mode difficult to understand version:
char *remove_char(char *str, int c)
{
char *pos = str;
char *wrk = str;
while(*wrk)
{
if(*wrk == c)
{
*wrk++;
continue;
}
*pos++ = *wrk++;
}
*pos = 0;
return str;
}
Both require the string to be writable (so you cant pass the pointer to the string literal for example)
int *i;
ters_cevir(){
char *term=i;
char *som=i;
char som1;
while (*term != '\0') { term++; }
while (*som != '\0') {
som1=som*;
*term=som;
term--;
som++;
}
}
int main() {
char *isim=malloc(sizeof(char));
i=&isim;
printf("Reverse words=");
scanf("%s",isim);
printf("Kelimenizin tersi:\n ");
ters_cevir(); // When I call this, it must make the reverse one that make from memory
while (*isim != '\0') {
printf("%c",*isim);
isim++;
sayac++;
}
return 0;
}
Hi I have modified your code. Please see below also see my comments:-
void ters_cevir(char *isim){
char *term=isim;
//char *som=isim;
//char som1;
while (*isim != '\0') { isim++; }
while (*term != '\0') {
//som1=som*;
*--isim=*term++//isim was pointing to the null character so we are pre decrement that pointer and post decrement term
//here we are coping the string in reverse order in isim
//term--;
//som++;
}
}
int main() {
char *isim=malloc(50);//you need enough space to store a string. you have just allocated only one byte which was not enough
//i=&isim;
printf("Reverse words=");
scanf("%s",isim);
printf("Kelimenizin tersi:\n ");
ters_cevir(isim); // now it will work fine. Here you are passing the address of isim
while (*isim != '\0') {
printf("%c",*isim);
isim++;
sayac++;
}
return 0;
}
Your code does not compile because of syntax errors such as som1=som*;
You should pass the string as an argument to ters_cevir(); instead of a global variable i with an incorrect type int *.
After fixing these problems, ters_cevir() will still not achieve the expected result because it overwrites the string from the end with characters from the start, with an off by one error.
You could correct this by swapping characters at *som and *term, but be careful to stop when som >= term otherwise you will reverse the string twice.
Futhermore, the code in main is completely broken.
Here is a corrected version:
#include <stdio.h>
char *reverse(char *str) {
char *term = str;
char *som = str;
char c;
while (*term != '\0') { term++; }
while (som < term) {
term--;
c = *som;
*som = *term;
*term = c;
som++;
}
return str;
}
int main() {
char buf[128];
printf("String to reverse: ");
if (scanf("%127[^\n]", buf) == 1) {
printf("Reversed string: %s\n", reverse(buf));
}
return 0;
}
I am attempting to create a program that will allow a user to search for a name in a file. The program does this successfully, but then it occurred to me that not everyone will type in the name as it is capitalized in the file. That is, someone may search for "sarah," but as the name is listed as "Sarah" in the file the name will not be found. To get around this I have attempted to convert both strings into upper case at the time of comparison. I am very, very new to teaching myself C, so I am not certain if I am even heading in the right direction. At this point I cannot even get the program to compile as I am getting two errors that say "array initializer must be an initializer list or string literal." I'm assuming that to mean that my syntax is not only invalid but completely in the wrong direction. What would be the best way to approach my goal?
#include <stdio.h>
#include <ctype.h>
#include <string.h>
int main(void)
{
FILE *inFile;
inFile = fopen("workroster.txt", "r");
char rank[4], gname[20], bname[20], name[20];
printf("Enter a name: __");
scanf("%s", name);
int found = 0;
while(fscanf(inFile, "%s %s %s", rank, bname, gname)== 3)
{ char uppername[40] = toupper(name[15]);
char upperbname[40] = toupper(bname[15]);
if(strcmp(uppberbname,uppername) == 0)
{
printf("%s is number %s on the roster\n", name, rank);
found = 1;
}
}
if ( !found )
printf("%s is not on the roster\n", name);
return 0;
}
This two lines are wrong:
char uppername[40] = toupper(name[15]);
char upperbname[40] = toupper(bname[15]);
int toupper(int c); takes an int and returns an int
Because in C string is just an array of chars with a null terminator, so what you can do is to convert each character of the string to uppercase:
for (size_t I = 0; I < strlen(name); I++) {
uppername[I] = toupper(name[I]);
}
uppername[I] = '\0';
Regarding compare, you can use strcasecmp as suggested, which is Posix.
If you want to just use function in the C stdlib, convert the string as above, and then use strcmp.
toupper() works on a single character, not on a string.
No need to convert the input strings. Simple call a string case-insensitive compare.
As C does not have a standard one, it is easy enough to create your own.
int mystricmp(const char *s1, const char *s2) {
// toupper works with unsigned char values.
// It has trouble (UB) with char, when char is signed.
const unsigned char *p1 = (const unsigned char *) s1;
const unsigned char *p2 = (const unsigned char *) s2;
while (toupper(*p1) == toupper(*p2) && *p1) {
p1++;
p2++;
}
int ch1 = toupper(*p1);
int ch2 = toupper(*p1);
return (ch1 > ch2) - (ch1 < ch2);
}
use the following function, which is included in strings.h
int strcasecmp(const char *s1, const char *s2);
in your case change if statement
if(strcmp(uppberbname,uppername) == 0)
to
if(strcasecmp(bname,name) == 0)
and delete
char uppername[40] = toupper(name[15]);
char upperbname[40] = toupper(bname[15]);
Because the function toupper is for converting a character from small to capital, you cannot use it for a string case conversion. But you can string using the same function in this way:
while(name[i])
{
uppername[i]=toupper(name[i]);
i++;
}
while(bname[j])
{
upperbname[j]=toupper(bname[j]);
j++;
}
These statements do our string case conversion. The whole Program:
#include <stdio.h>
#include <ctype.h>
#include <string.h>
int main(void) {
FILE *inFile;
inFile = fopen("workroster.txt", "r");
char rank[4], gname[20], bname[20], name[20], uppername[40], upperbname[40];
printf("Enter a name: __");
scanf("%s", name);
int found = 0, i = 0, j = 0;
while (fscanf(inFile, "%s %s %s", rank, bname, gname) == 3) {
while (name[i]) {
uppername[i] = toupper(name[i]);
i++;
}
while (bname[j]) {
upperbname[j] = toupper(bname[j]);
j++;
}
//char uppername[40] = toupper(name[15]);
//char upperbname[40] = toupper(bname[15]);
if (strcmp(uppername, upperbname) == 0) {
printf("%s is number %s on the roster\n", name, rank);
found = 1;
}
}
if (!found) printf("%s is not on the roster\n", name);
return 0;
}
I want to capitalize the first character of a pointer string.
For example, input: john
Output: John
I can do it with arrays (s[0] = toUpper(s[0]), but is there a way to do it with pointers?
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#define MAX 30
int transform(char *s)
{
while (*s != '\0')
{
*s = toupper(*s);
s++;
}
return *s;
}
int main()
{
printf("String: ");
char *s[MAX];
getline(&s,MAX);
transform(s);
printf("Transformed char: %s", &s);
}
int getline(char *s, int lim)
{
int c;
char *t=s;
while (--lim>0 && (c=getchar())!=EOF && c!='\n') *s++=c;
*s='\0';
while (c!=EOF && c!='\n')
c=getchar();
return s-t;
}
This code turns the whole string to upper case.
Your transform function is looping through the entire string and running toupper on each one. Just run it on the first character:
void transform(char *s)
{
*s = toupper(*s);
}
Also, you declare s in main as an array of pointers to char. You just want an array of char:
int main()
{
printf("String: ");
char s[MAX];
getline(s,MAX); // don't take the address of s here
transform(s);
printf("Transformed char: %s", s); // or here
}
You want to move main to the end of the file as well, so that getline is defined before it is called.
Easy solution:
void transform(char* p) {
//Only first character
*p = toupper(*p);
}
//Call like that:
char str[] = "test";
transform(str); //str becomes: "Test"
Basically, I want to display the words and their number of occurrences in a string. It can be both case sensitive and vice-versa.
For e.g if the input string is "Hello World How are you Hello how", the output should be:
Hello,2
World,1
How,2
are,1
you,1
I am not able to figure out the logic for this yet; any help?
Use
fgets()
strtok_r()
strcmp()
Check these three APIs. Figure out the code-to-write, implement, run into issues, come back and we'll be here to help.
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdbool.h>
bool eq(const char *s, const char *w, char ignore_case){
char si, wi;
while(*w && !isspace(*w)){
if(ignore_case != 'n'){
si = tolower(*s++);
wi = tolower(*w++);
} else {
si = *s++;
wi = *w++;
}
if(si != wi)
return false;
}
return !*s || isspace(*s);
}
char *next_word(char *w){
while(*w && !isspace(*w))
++w;
if(!*w)
return w;
while(isspace(*w))
++w;
return w;
}
int main() {
char ignore_case = 'n';
char *word, *str;
char string[128];
printf("ignore case ?(y/n):");
scanf("%c", &ignore_case);
printf("input string : ");
scanf(" %127[^\n]", string);
str = string;
while(*str){
int counter = 1;
word = next_word(str);//skip first word
while(*word){
char *p = NULL;
if(eq(str, word, ignore_case)){
p = word;
++counter;
}
word = next_word(word);//move to next word top
if(p)
memset(p, ' ', word - p);//clear already match word
}
word = str;
str = next_word(str);
while(*word && !isspace(*word))
putchar(*word++);
printf(",%d\n", counter);
}
return 0;
}