how to kill allien characters in my string? - c

what i want to do is take a big input(read till users press enter(\n) ) and then call a function that puts the first word of this input(read till ' '). My problem is that even though it looks pretty simple it also has 2 extra allien characters in it. This is my code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
void findChoise(char *input, char *choise);
int main()
{
char choise[12];
char input[300];
printf("give me the input: ");
gets(input);
printf("%s\n", input);
printf("%s%d\n", "length of input: ", strlen(input));//for checking
findChoise(input, choise);
printf("%s%d\n", "length of output: ", strlen(choise));//for checking
printf("%s\n", choise);
return 0;
}
void findChoise(char *input, char *choise)
{
int i=0;
while(input[i] != ' ')
{
choise[i] = input[i];
i++;
};
}

What you have already done is very close. You are just missing the null character at the end of the string ("\0"). I have cleaned up your code a little bit and fixed somethings. Please read through it and try and understand what is going on.
Main things to note:
All strings are arrays of characters and terminates with a null character "\0"
When you declare buffers(input and choice), try to make them a power of 2. This has to due with how they are stored in memory
Avoid using gets and try scanf instead
#include <cstdio>
void findChoice(char*, char*);
int main() {
char choice[16];
char input[512];
scanf("%s", input);
findChoice(choice, input);
printf("%s", choice);
return 0;
}
void findChoice(char* input, char* choice) {
int i = 0;
while(input[i] != ' ') {
choice[i] = input[i];
++i;
}
choice[i] = '\0';
}

You also need to write a null character to end the choise string:
void findChoise(char *input, char *choise)
{
int i=0;
while(input[i] != ' ')
{
choise[i] = input[i];
i++;
}
choise[i] = 0;
}
also don't use gets:
fgets(input, sizeof(input), stdin);
and use %zu to print size_t:
printf("%s%zu\n", "length of input: ", strlen(input));

Related

How can I stop the input when I enter end

got this little problem, I made this code for my task, it should input strings and print it in revese, the loop should end when you enter end, but it doesnt end, I know this is not how you check strings but I don't know how to correct it. Thanks in advance for help.
#include <stdio.h>
#include <stdlib.h>
void reverse(char str[]){
int length;
for(length=strlen(str)-1; length >= 0; length--){
printf("%c",str[length]);
}
}
int main(void){
char str[]="";
while(str != "end"){
printf("\nEnter string: ");
scanf("%s", str);
reverse(str);
}
return 0;
}
you have many problems in your code :
when you write char str[]=""; this is will create a string of size = 1 only which will not accept any string you enter except for only one char , so you should do char str[50]; where 50 is the max expected length of the entered string.
it's not while(str != "end") it's , while(strcmp(str,"end") != 0) as you want to compare the strings itself not addresses
it's better to write scanf("%49s", str); than scanf("%s", str); just to make sure that the entered string will always fit in your array
in this line length = strlen(str)-1; , the strlen function return unsigned long long , so you should typecast that and write length = (int)strlen(str)-1; instead
with this all being said , this is the edited code :
#include <stdio.h>
#include <string.h>
void reverse(char str[]){
int length;
for(length = (int)strlen(str)-1; length >= 0; length--){
printf("%c",str[length]);
}
}
int main(void){
char str[50];
while(strcmp(str,"end") != 0){
printf("\nEnter string: ");
scanf("%49s", str);
reverse(str);
}
return 0;
}
and this is the output:
Enter string:abcd
dcba
Enter string:end
dne
Process finished with exit code 0

Do-while or while loop that will keep taking an input from user but will terminate after I input the string "exit" (case insensitive) in c language

#include <stdio.h>
#include <ctype.h>
int main() {
char str[100];
char out[] = "exit";
do {
printf("Enter a string: ");
scanf("%s", str);
// some if else statement here
} while (toupper(str[3]) != toupper(out[3]));
}
I put the index 3 because if I put the index 0 there, the code will terminate if the entered string starts with letter e. I tried the while loop but it does not work for me. Also I want to print a prompt message that says "detected terminate keyword" after entering the word "exit" and then terminates the loop.
You will also notice the toupper() function. I used it there because I want my loop to be case insensitive, so regarless of lowercase or uppercase or combination of both, the loop should terminate when the word "exit" is entered.
toupper(str[3]) != toupper(out[3]) will compare the upper case 4th letter of str and out, so the loop will iterate till str[3] is 'T'. You want to use strcasecmp(str, out) instead. Remember to #include <strings.h>.
There are multiple problems:
it is confusing for a function isPalindrome() to return 0 for true.
to avoid undefined behavior on negative char values, a char argument to toupper should be cast as (unsigned char).
the test for the exit keyword is incorrect. You exit if the fourth letter is a t or a T. You should use strcasecmp to test for the exit word.
scanf("%s", str) has potential undefined behavior if the user enters a word with more than 99 bytes. Use scanf("%99s", str) and test the return value: it must be 1 for a successful conversion.
instead of a confusing do / while loop, use a for (;;) loop (also known as for ever loop), and test for 2 exit conditions: scanf() failure to read a word and reading the word exit.
#include <ctype.h>
#include <stdio.h>
#include <string.h>
int isPalindrome(const char *str) {
size_t len = strlen(str);
for (size_t i = 0; i < len; i++) {
if (toupper((unsigned char)str[i]) != toupper((unsigned char)str[len - i - 1]))
return 0;
}
return 1;
}
int main() {
char str[100];
for (;;) {
printf("Enter a string: ");
if (scanf("%99s", str) != 1)
break;
if (!strcasecmp(str, "exit"))
break;
if (isPalindrome(str)) {
printf("%s is a palindrome!\n\n", str);
} else {
printf("%s is not a palindrome!\n\n", str);
}
}
return 0;
}
I put the index 3 because if I put the index 0 there, the code will terminate if the entered string starts with letter e
Exactly, and the code:
while (toupper(str[3]) != toupper(out[3])
Suffers from the same problem, any input with a t as its 4th character index 3 will match and the loop will end, you are comparing a specific character of the string, not the string itself. You can use strcasecmp to assess if the input is indeed exit and ignore casing.
Furthermore using %s specifier is not good, you run the risk of overrunning the destination buffer. You should use a width, %99s for a 100 characters buffer to leave space for the nul byte, if possible consider using fgets instead.
#include <stdio.h>
#include <ctype.h>
#include <string.h>
int main() {
char str[100];
char out[] = "exit";
do {
printf("Enter a string: ");
scanf(" %99s", str); // space before specifier to clean leading whitespaces
// some if else statement here
} while (strcasecmp(str, out) != 0);
puts("Detected terminate keyword. Goodbye!");
}
char *removeLastChar(char *str, char ch)
{
size_t len;
if(str)
{
len = strlen(str);
if(str[len - 1] == ch) str[len -1] = 0;
}
return str;
}
char *strlwr(char *str)
{
char *wrk = str;
if(str)
{
while(*wrk)
{
*wrk = tolower((unsigned char)*wrk);
wrk++;
}
}
return str;
}
int main(void)
{
char str[100];
const char *out = "exit";
int x = 0;
do
{
printf("Enter a string: ");
if(!fgets(str, sizeof(str), stdin)) break;
removeLastChar(str, '\n');
printf("You entered: \"%s\"\n:", str);
} while (strcmp(strlwr(str), out));
}

Print the first letter of each word in a sentence

I am learning C programming and I am trying to print the first letter of each word in a sentence. I have written this code below but it doesn't seem to be working.
#include<stdio.h>
#include<string.h>
int main()
{
char s[100];int i,l;
scanf("%s",&s);
l=strlen(s);
printf("%c",s[0]);
for(i=0;i<l;i++)
{
if(s[i]==' ')
{
printf("%c",s[i+1]);
}
}
}
Input: Hello World
Expected Output: HW
Actual Output: (nothing)
The problem is in how you're reading the input:
scanf("%s",&s);
The %s format specifier to scanf reads characters until it encounters whitespace. This means it stops reading at the first space.
If you want to read a full line of text, use fgets instead:
fgets(s, sizeof(s), stdin);
just Change %s at scanf() to:
%[^\n]
This makes it scans until it finds an enter.
scanf("%[^\n]", &inisial);
#include <stdio.h>
#include <string.h>
int main()
{
char str1[100];
char newString[10][10];
int i,j,ctr;
printf(" Input a string : ");
fgets(str1, sizeof str1, stdin);
j=0; ctr=0;
for(i=0;i<=(strlen(str1));i++)
{
if(str1[i]==' '||str1[i]=='\0')
{
newString[ctr][j]='\0';
ctr++;
j=0;
}
else
{
newString[ctr][j]=str1[i];
j++;
}
}
for(i=0;i < ctr;i++)
{
printf(" %c\n",(newString[i])[0]);
}
return 0;
}
//Here is your working code

C: Program skips next input

My program skips the next input after 1 pass through it. I have read the threads on removing the newline character that fgets has, but nothing that was suggested worked. Is there anything that would work with microsoft visual studio? The best suggestion was "words[strcspn(words, "\r\n")] = 0;" and this did not remove the new line, unless I am formatting it incorrectly. I am not allowed to use the strtok function.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SIZE 50
#define STOP "quit\n"
char *copywords(char *dest, const char *source, size_t n);
int main(void)
{
char words[50];
char newwords[50];
size_t num;
for (;;) {
printf("\nType a word, or type 'quit' to quit: ");
(fgets(words, SIZE, stdin));
if (strcmp(words, STOP) == 0) {
printf("Good bye!\n");
return 0;
}
printf("Type the # of chars to copy: ");
scanf_s("%d", &num);
copywords(newwords, words, num);
printf("The word was %s\n", words);
printf("and the copied word is %s", newwords);
}
}
char *copywords(char *dest, const char *source, size_t n) {
size_t i;
for (i = 0; i < n && source[i] != '\0'; i++) {
dest[i] = source[i];
}
dest[i] = '\0';
return dest;
}
The problem is that you leave the \n on the input when you call scanf. i.e. the user types number[return]. You read the number. When you loop around and call fgets agains the return is still waiting to be read so thats what fgets gets and it returns immediately.
I would probably just call fgets the second time you want to read input as well and then use sscanf to read from the string. i.e.
printf("Type the # of chars to copy: ");
fgets(buffer, ...)
sscanf(buffer, "%d", ...)
As an aside I would also say to check return values as it is easy for fgets or *scanf to fail.
My program skips the next input after 1 pass through it.
If I understand you correctly, the problem is that scanf_s (which I assume is like the C standard's scanf) will read the digits into num, but scanf won't remove the following newline from stdin, and so in the next iteration of the loop fgets will see that newline and behave as if it had seen a blank line.
I have usually avoided scanf for this reason and instead read a line into a buffer and then parse it. For example:
char buf[50];
...
fgets(buf,sizeof(buf),stdin);
sscanf(buf,"%d",&num);
(I'd also recommend adding a whole lot more error checking throughout.)
Here's a straightforward solution.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SIZE 50
#define STOP "quit\n"
char *copywords(char *dest, const char *source, size_t n);
int main(void)
{
char words[50];
char newwords[50];
size_t num, run = 0;
for (;;) {
printf("\nType a word, or type 'quit' to quit: ");
if(run)
getchar();
(fgets(words, SIZE, stdin));
if (strcmp(words, STOP) == 0) {
printf("Good bye!\n");
return 0;
}
printf("Type the # of chars to copy: ");
scanf("%d", &num);
copywords(newwords, words, num);
printf("The word was %s\n", words);
printf("and the copied word is %s", newwords);
run = 1;
}
}
char *copywords(char *dest, const char *source, size_t n) {
size_t i;
for (i = 0; i < n && source[i] != '\0'; i++) {
dest[i] = source[i];
}
dest[i] = '\0';
return dest;
}
Since we know there will be an extra '\n' character left in the stream due to the scanf, just take it out.

how to reverse the integers between two strings with changing lower to upper & upper to case alphabets in c

I have an input string such as :"Hello 12345 WoRlD"
and I want output it as : "hELLO 54321 wOrLd"
1)here the lower case should be converted to upper and vice versa
2)reverse the integers between two strings
after executing it will only prints first string only and the rest of output vanishes
Here is what I have attempted so far
#include<stdio.h>
#include<string.h>
char* casechange(char *);
main()
{
char s[30],*p,*q;
int i,j;
printf("Enter string data:");
scanf("%s",s);
q=casechange(s);
printf("Manipulated string data:%s\n",s);
}
char* casechange(char *s)
{
int i,j=strlen(s)-1,num;
for(i=0;s[i];i++)
{
if(s[i]>='a'&&s[i]<='z')
{
s[i]-=32;
}
else if(s[i]>='A'&&s[i]<='Z')
{
s[i]+=32;
}
}
if(s[i]>='0'&&s[i]<='9'&&s[j]>='0'&&s[j]<='9')
//for(i=0;i<j;i++,j--)
//{
{
num=s[i];
s[i]=s[j];
s[j]=num;
}
//}
return s;
}
How can this be accomplished?
The problem with "after executing it will only prints first string only and the rest of output vanishes" is:
scanf("%s",s);
The scanf() '%s' format string tells scanf to read in a string, but only up to the first space. Hence, if you enter:
"Hello 12345 WoRlD"
The scanf("%s", s) will copy only "Hello" into 's'.
To fix this, change:
scanf("%s",s);
To this:
fgets(s, sizeof(s), stdin);
However, fgets() may leave a unwanted '\n' at the end of the string. The unwanted '\n' can be eliminated by inserting the following code after the fgets():
q=strchr(s,'\n');
if(q)
*q = '\0';
Then the output will be:
"hELLO 12345 wOrLd"
SPOILER ALERT!
See my version 'casechange()', which will also reverse the number.
#include <stdio.h>
#include <string.h>
#include <ctype.h>
char* casechange(char *);
int main(){
char s[30];
printf("Enter string data:");
scanf("%29[^\n]",s);//%s : separated by white space
casechange(s);
printf("Manipulated string data:%s\n", s);
return 0;
}
char* casechange(char *s){
int i;
for(i=0;s[i];i++){
if(islower(s[i]))
s[i] = toupper(s[i]);
else if(isupper(s[i]))
s[i] = tolower(s[i]);
else if(isdigit(s[i])){
int j, n;
char num[30];
sscanf(&s[i], "%29[0123456789]%n", num, &n);
for(j=0;j<n;++j)
s[i+j] = num[n-j-1];
i+=n-1;
}
}
return s;
}
else if(isdigit(s[i])){
int j, n;
char num;
sscanf(&s[i], "%*[0123456789]%n", &n);
for(j=0;j<n/2;++j){
num = s[i+j];
s[i+j] = s[i+n-j-1];
s[i+n-j-1] = num;
}
i+=n-1;
}

Resources