#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
int main(){
char str [1000] = "";
char ch = 'M';
char *findM;
printf("Enter a line of text\n");
scanf("%s", str);
findM = strchr(str, ch);
printf("string after %c is %s ", ch, findM);
return 0;
}
The input to the program is "My name is Steve", and the output of this program becomes, string after M is (null) Why is this occurring?
As mentioned in one of the comments, scanf("%s", str) reads until it finds a trailing white space. In your input "My name is Steve" scanf will read up to My since there is a space after My.
Assuming that your input only contains numbers,letters, and spaces you could try the following:
int main()
{
char str[1000] = "";
char ch = 'M';
char *findM;
printf("Enter a line of text\n");
scanf("%999[0-9a-zA-Z ]", str); // Get all alphanumerics and spaces until \n is found
findM = strchr(str, ch);
findM++; // Increment the pointer to point to the next char after M
printf("string after %c is %s ", ch, findM);
return 0;
}
If you are not required to use scanf(), I will recommend staying away from scanf() and using fgets() instead:
int main()
{
char str[1000] = "";
char ch = 'M';
char *findM;
printf("Enter a line of text\n");
fgets(str, sizeof(str), stdin); // Get the whole string
findM = strchr(str, ch);
findM++; // Increase the counter to move to the next char after M
printf("string after %c is %s ", ch, findM);
return 0;
}
You would get null if the method does not find any matches, it is possible that your input does not have 'M'
for more details : http://www.cplusplus.com/reference/cstring/strchr/
Probably your str variable doesn't contain the char 'M' in the first word - The strchr(string, char) function returns null if no match is found and cuts off the input string after the first whitespace (excluding leading whitespaces). As user3121023 mentioned in their comment, use fgets instead to capture multi-word input.
strchr() is considering ' ' (space )as a delimiter so give you input withiut a space it works fine ..
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
int main()
{
char str [1000] = "";
char ch = 'M';
char *findM;
printf("Enter a line of text\n");
scanf("%s", str);
findM = strchr(str, ch);
if(findM)
printf("string after %c is %s ", ch, findM);
else
printf("Character not found ...\n");
return 0;
}
Related
I'm having trouble looping through a string and replacing instances of a character with a new character. I'm attempting to do so with a function that I've called replace.
// C program to replace all occurrences of a character with another in a string
#include <stdio.h>
#include <string.h>
/* Function declaration */
void replace(char *string, char toReplace, char replaceWith);
int main()
{
char string[100];
char toReplace, replaceWith;
printf("Enter any string: ");
scanf("%s", string);
printf("Enter character to replace: ");
scanf("%c\n", &toReplace);
getchar();
printf("Enter character to replace '%c' with: ", toReplace);
scanf("%c\n", &replaceWith);
replace(string, toReplace, replaceWith);
// print new string
printf("%s\n", string);
return 0;
}
// Replaces the all occurrence of a character with another in given string.
void replace(char *string, char toReplace, char replaceWith)
{
for (int i = 0; i <= strlen(string); i++)
{
if (string[i] == toReplace)
{
string[i] = replaceWith;
}
}
}
Snippets of code causing me the most grief are:
printf("Enter character to replace '%c' with: ", toReplace);
Does not print what I expect it to.
if (string[i] == toReplace)
Treats string[i] as the entire string, and not the individual members of the string.
Changing
scanf("%c\n", &toReplace);
to
scanf(" %c", &toReplace); helped, as this now ignores leading whitespace.
Your replace function is OK except for a few details:
you should not recompute the length of the string at each iteration, especially as the compiler cannot assume the string to be constant since it gets modified inside the loop.
the test should be i < len where len is the length of the string. It seems incorrect to test the null terminator for replacement.
i should be defined with type size_t instead of int.
The problem you observe is linked to your usage of scanf():
"%c\n" will read the pending newline from stdin and then consume any subsequent white-space, which should not occur as the user typed the character they were prompted for. The next call will read this character, consume the newline and leave the second character typed pending in stdin. You should use scanf(" %c", &toReplace) instead.
note also that scanf("%s", string); will stop at the first white-space character and may cause a buffer overflow. Using fgets() seems a better approach for this.
Here is a modified version:
#include <stdio.h>
#include <string.h>
/* Function declaration */
void replace(char *string, char toReplace, char replaceWith);
int main() {
char string[100];
char toReplace, replaceWith;
printf("Enter any string: ");
if (!fgets(string, sizeof string, stdin))
return 1;
printf("Enter character to replace: ");
if (scanf(" %c", &toReplace) != 1)
return 1;
printf("Enter character to replace '%c' with: ", toReplace);
if (scanf(" %c", &replaceWith) != 1)
return 1;
replace(string, toReplace, replaceWith);
// print new string
printf("%s", string);
return 0;
}
// Replaces the all occurrence of a character with another in given string.
void replace(char *string, char toReplace, char replaceWith) {
for (size_t i = 0, len = strlen(string); i < len; i++) {
if (string[i] == toReplace) {
string[i] = replaceWith;
}
}
}
#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));
}
I mean we have MAX_LENGTH value, so I want to cap the string formatting length
using it but not a number like 12.
#include <stdio.h>
#define MAX_LENGTH 12
int main(void) {
char first_name[MAX_LENGTH + 1], last_name[MAX_LENGTH + 1];
printf("Пожалуйста, введите ваше имя: ");
scanf("%12s", first_name);
char ch; // Clearing the buffer to fix a bug when the input
while((ch = getchar()) != '\n' && ch != EOF); // string lenght is greater than MAX_LENGTH.
printf("Пожалуйста, введите фамилию: "); // So, I made it 12 just to show that in case of string length > 12
scanf("%12s", last_name); // the program doesn't crash but just cuts the string.
printf("Ваши данные: %s %s\n", last_name, first_name);
return 0;
}
I'd wanted to do something like
printf("%.*s", MAX_LENGTH, string);
but with the scanf function. Just to not be fixing it every time I change MAX_LENGTH.
You can use any string as a format of the scanf. It can be also a variable.
#include <stdio.h>
int main(void)
{
char format[16];
char string[16];
size_t maxLength;
if(scanf("%zu", &maxLength) != 1) { /* handle error */}
sprintf(format, "%%%zus", maxLength);
if(scanf(format, string) != 1) { /* handle error */}
printf("`%s`\n", string);
}
Result:
`12345`
I am new to C language and I am trying read a character and a string (a sentence; max-length 25) from a user.
Not sure what I am doing wrong in the following lines of code, its giving me an error "Segment Fault".
#include <stdio.h>
int main(){
char * str[25];
char car;
printf("Enter a character: ");
car = getchar();
printf("Enter a sentence: ");
scanf("%[^\n]s", &str);
printf("\nThe sentence is %s, and the character is %s\n", str, car);
return 0;
}
Thanks!
You have to make four changes:
Change
char * str[25];
to
char str[25];
as you want an array of 25 chars, not an array of 25 pointers to char.
Change
char car;
to
int car;
as getchar() returns an int, not a char.
Change
scanf("%[^\n]s", &str);
to
scanf( "%24[^\n]", str);
which tells scanf to
Ignore all whitespace characters, if any.
Scan a maximum of 24 characters (+1 for the Nul-terminator '\0') or until a \n and store it in str.
Change
printf("\nThe sentence is %s, and the character is %s\n", str, car);
to
printf("\nThe sentence is %s, and the character is %c\n", str, car);
as the correct format specifier for a char is %c, not %s.
str is an array of 25 pointers to char, not an array of char. So change its declaration to
char str[25];
And you cannot use scanf to read sentences--it stops reading at the first whitespace, so use fgets to read the sentence instead.
And in your last printf, you need the %c specifier to print characters, not %s.
You also need to flush the standard input, because there is a '\n' remaining in stdin, so you need to throw those characters out.
The revised program is now
#include <stdio.h>
void flush();
int main()
{
char str[25], car;
printf("Enter a character\n");
car = getchar();
flush();
printf("Enter a sentence\n");
fgets(str, 25, stdin);
printf("\nThe sentence is %s, and the character is %c\n", str, car);
return 0;
}
void flush()
{
int c;
while ((c = getchar()) != '\n' && c != EOF)
;
}
// This is minimal change to your code to work
#include <stdio.h>
int main(){
char car,str[25];
printf("Enter a character: ");
car = getchar();
printf("Enter a sentence: ");
scanf("%s", str);
printf("\nThe sentence is %s, and the character is %c\n", str, car);
return 0;
}
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));