I wrote the following code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SIZE 128
int main ()
{
char mychar , string [SIZE];
int i;
int const count =0 ;
printf ("Please enter your string: \n\n");
fgets (string, SIZE, stdin);
printf ("Please enter char to find: ");
mychar = getchar();
for (i=0 ; (string[i] == '\0') ; i++ )
if ( string[i] == mychar )
count++;
printf ("The char %c appears %d times" ,mychar ,count);
return 0;
}
The problem is that the gcc gives me an error for the 'int const count': " increment of read-only variable ‘count’".
What seems to be wrong ?
Thank !
Try using fgets instead as:
fgets (string, SIZE, stdin);
Why gets is unsafe, has been answered several times on SO. You can see this.
Always use fgets() instead of gets. Also there are lots of stuff to fix. You shouldnt use standard library functions for creating user interface. Standard library is really not designed for that. Instead you should use curses library or something similar. You could also write the program to accept arguments as input.
Short example of proper use of the standard library. This version does not have any error checking so it assumes that user input is correct.
#include <stdio.h>
int main(int artc, char *argv[])
{
/* arguments are strings so assign only the first characte of the
* third argument string. Remember that the first argument ( argv[0] )
* is the name of the program.
*/
char mychar = argv[2][0];
char *string = argv[1];
int i, count = 0;
/* count the occurences of the given character */
for(; *string != '\0'; ++string)
if(*string == mychar) ++count;
printf("The char ‘%c’ appears %d times.\n", mychar, count);
return 0;
}
Usage: ./count "Hello, World!" l
Output: The char ‘l’ appears 3 times.
EDIT: As for the original code. Change == to !=.
for (i=0 ; (string[i] == '\0') ; i++ )
to:
for (i=0 ; (string[i] != '\0') ; i++ )
The comparison was wrong.
To make this example work you should also change the line:
if(*string == mychar) ++count;
into
if(string[i] == mychar) ++count;
Full working example is now:
#include <stdio.h>
int main(int artc, char *argv[])
{
/* arguments are strings so assign only the first characte of the
* third argument string. Remember that the first argument ( argv[0] )
* is the name of the program.
*/
char mychar = argv[2][0];
char *string = argv[1];
int i, count = 0;
/* count the occurences of the given character */
for (i=0 ; (string[i] != '\0') ; i++ )
if(string[i] == mychar) ++count;
printf("The char ‘%c’ appears %d times in the sentence: %s\n", mychar, count, string);
return 0;
}
Consider replace with "scanf( "%s", &string)" instead.
gets is dangerous because it lets you read in more data than you've allocated space for, you can use fgets which specifies how many characters it is going to read in and stops if it finds a newline.
gets is dangerous because it can take in more data than the size of the variable. Thereby exposing the system to attacks and compromising security.
fgets should be used as it limits no. of characters to be read.
This will do:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SIZE 128
int main()
{
char mychar, string[SIZE];
int i;
int count=0;
printf("Please enter your string: ");
fgets(string, SIZE, stdin);
printf("Please enter char to find: ");
mychar = getchar();
for (i = 0; (string[i] != '\0'); i++)
if (string[i] == mychar) ++count;
printf("The char %c appears %d times in the sentence: %s" ,mychar ,count, string);
return 0;
}
Related
This is one of the assignments for my class and this is the objective of the assignment:
Write a program whose input is a character and a string, and whose output indicates the number of times the character appears in the string. The output should include the input character and use the plural form, n's, if the number of times the characters appears is not exactly 1. You may assume that the string does not contain spaces and will always contain less than 50 characters.
This is the code I have so far and I am new to C programming so I don't know how to declare Strings correctly just yet. So far I learned there are no strings in C like there is in Java and you have to do them as a character array:
#include <stdio.h>
#include <string.h>
int main(void) {
char userChar;
char userString[50];
int count = 0;
for (int i = 0; i < userChar; i++) {
if (userString[i] == userChar)
count++;
}
printf("%d", count);
if (count != 1)
printf("'s");
return 0;
}
For example, if I wanted to input n Monday and output 1 n
What would I need to change in my code to go from n Monday to 1 n
This is the only output I am getting, and it only has outputted one thing correctly:
0's
First, I hope this is not considered cheating :-)
Second, you need to define userChar and userString as arguments for main, and pass them in at run time. They are assigned nothing, so that is why you get
0's
Third, your for condition is wrong. You need this so it only iterates through the length of the string:
for (int i = 0; i < strlen(userString); i++)
Finally, You are not printing the value of userChar prior to the return
At first you need to input a string and a character. To count the number of occurrences of the character in the string you can use standard string function strchr.
The program can look something like the following
#include <stdio.h>
#include <string.h>
int main(void)
{
char userChar = ' ';
char userString[50] = "";
printf( "Enter a string without embedded spaces\nof the length less than %d: ", 50 );
scanf( "%49s", userString );
printf( "Enter a character to search in the string: " );
scanf( " %c", &userChar );
size_t n = 0;
for ( const char *p = userString; ( p = strchr( p, userChar ) ) != NULL; ++p )
{
++n;
}
printf( "%zu%s %c\n", n, n < 2 ? "" : "'s", userChar );
}
The expected output is not 0's, it should include the counted character: for example if the character is n and the string Monday, the output should be
1 n
and if the string is Eeny-meeny-miny-moe, the output would be
3 n's
Here is a modified version:
#include <stdio.h>
int main() {
char userChar;
char userString[50];
int i, count;
printf("Enter character: ");
scanf(" %c", &userChar);
printf("Enter string (single word): ");
// read a word with at most 49 characters
scanf(" %49s", userString);
count = 0;
for (i = 0; userString[i] != '\0'; i++) {
if (userString[i] == userChar)
count++;
}
printf("%d %c", count, userChar);
if (count != 1)
printf("'s");
printf("\n");
return 0;
}
This might be a rookie question, but I need to make sure that the input given by the user is of data type char [%c] or a string [%s].
If it were an integer, I would just do something like this:
int data, x;
do {
printf("Please enter a number: ");
x = scanf(" %d", &data);
getchar();
} while(x!=1);
So I was wondering if there's a similar way to do this, if the input is supposed to be a string or a character. Thanks, Any help would be appreciated!
Avoid to use %c in scanf() because some unexpected character like \r\n will be input.
You can use a char[2] to receive a single character. An \0 will be filled after your string to represent the end of string, so the length of array must be bigger than 1.
An example:
#include <stdio.h>
int main()
{
char data[2];
scanf("%1s", data);
if (data[0] >= 'a' && data[0] <= 'z') // custom your constraint here
{
// legal
printf("legal: %s", data);
}
else
{
// illegal
printf("illegal: %s", data);
}
return 0;
}
While I input b, the data will be "b\0".
part of the answer is if you just want to read only alphabet you can use below.
#include <stdio.h>
#include <ctype.h>
int main()
{
char ch;
do {
printf("enter a char:");
scanf(" %c",&ch);
}while(!isalpha(ch));
printf("%c",ch);
return 0;
}
Update 1:
Just for the completeness and for the FUN part of the programing, have added code here.
This works well (not tested robustly, you can do if you need to) for the single char input or for a string of length 9.
Remember to type the EOF after input is entered in case length of input is < 9.
and read EOF behavior on same line and new line.
#include <stdio.h>
#include <ctype.h>
#define LEN 10
int main()
{
char ch;
char str[LEN] = {0};
int i = 0;
int ret;
printf("enter a char or string(len = 9) and press EOF if len < 9\n");
do {
if(1== (ret = scanf(" %c",&ch)))
{
if(isalpha(ch))
str[i++] = ch;
}
else
printf("scanf:Error (%d)\n", ret);
}while(ret != EOF && ( !isalpha(ch) || i < LEN-1));
str[i] = '\0';
printf("str is %s\n",str);
return 0;
}
I'm trying to make a program that will count how many letters occur in my string. I want only to count letters A and B on a give string.
char string[10];
int countA, countB;
gets(string);
for(int i = 0; i <strlen(string); i++){
if(string[i] == 'A')
countA++;
else if(string[i] == 'B')
countB++;
}
printf("%d %d", countA, countB);
return 0;
for example my input is: ABABA
the output should be 3 2 however it print a different answer for countB. I'm using devc++. Is this a bug?
Reason for getting different result:
Earlier when you didn't initialize the variable countA and countB they contained indeterminate value. Using them in your code introduces undefined behavior.
Two points:
Intialize the variables to zero. countA and countB.
And don't use gets rather use fgets.
I am giving you an example:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
int main(){
char string[10];
unsigned int countA=0, countB=0;
if( fgets(string,10,stdin) == NULL){
fprintf(stderr, "%s\n", "Error in string input");
exit(1);
}
size_t len = strlen(string);
if( len > 0 )
string[len-1]='\0';
for(size_t i = 0; i <strlen(string); i++){
if(string[i] == 'A'){
countA++;
}
else if(string[i] == 'B'){
countB++;
}
}
printf("%u %u", countA, countB);
return EXIT_SUCCESS;
}
Note:
Also you are asked whether it is gloabal variable. If it was then probably you wouldn't have to worry about initialization. They would be initialized with 0.
gets() goes on reading characters until it encounters \n or EOF. And on doing this it is not constrained in anyway with the buffer size, leaving a chance of buffer overflow.
I have I problem. I get 2 warnings from console, but I dont know what's wrong with my code. Can you have look?
Program suppose to show lines with at least 11 characters and 4 numbers
#include <stdio.h>
#include <ctype.h>
int main()
{
char line[200];
printf("Enter a string: \n");
while(fgets(line, sizeof(line),stdin))
{
int numberAlpha = 0;
int numberDigit = 0;
if(isalpha(line)) numberAlpha++;
else if(isdigit(line)) numberDigit++;
if(numberAlpha+numberDigit>10 && numberDigit>3) printf("%s \n", line);
}
return 0;
}
Both isalpha() and isdigit() takes an int, not a char *, as argument.
In your code, by passing the array name as the argument, you're essentially passing a char * (array name decays to the pointer to the first element when used as function argument), so, you're getting the warning.
You need to loop over the individual elements of line and pass them to the functions.
That said, just a suggestion, for hosted environment, int main() should be int main(void) to conform to the standard.
isalpha and isdigit are supposed to test if a char taken as int (a char can be safely converted to an int) is the encoding of an alphanumeric or digit character. You pass a char array, not an individual char. You need to test each char of the string you got, so you need a loop as:
for (int i=0; i<strlen(line); i++) {
if (isalpha(line[i])) numberAlpha++;
...
}
It is better to compute the length once:
int length = strlen(line);
for (int i=0; i<length; i++) {
...
}
You may also use a pointer to move along the string:
for (char *ptr = line; *ptr!=`\0`; ptr++) {
if (isalpha(*ptr)) ...
...
}
isalpha() and isdigit() functions take an int. But you are passing a char* i.e. the array line gets converted into a pointer to its first element (see: What is array decaying?). That's what the compiler complains about. You need to loop over line to find the number of digits and alphabets in it.
Also note that fgets() will read in the newline character if line has space. So, you need to trim it out before counting.
#include <stdio.h>
#include <ctype.h>
#include <string.h>
int main(void)
{
char line[200];
printf("Enter a string: \n");
while(fgets(line, sizeof(line),stdin))
{
int numberAlpha = 0;
int numberDigit = 0;
line[strcspn(line, "\n")] = 0; // Remove the trailing newline, if any.
for (size_t i = 0; line[i]; i++) {
if(isalpha((unsigned char)line[i])) numberAlpha++;
else if((unsigned char)isdigit(line[i])) numberDigit++;
}
printf("alpha: %d, digits:%d \n", numberAlpha, numberDigit);
}
return 0;
}
Ok, i got something like this:
#include <stdio.h>
#include <ctype.h>
int main()
{
char line[200];
printf("Enter a string: \n");
while(fgets(line, sizeof(line),stdin))
{
int numberAlpha = 0;
int numberDigit = 0;
int i;
for(i=0; i<strlen(line); i++){
if(isalpha(line[i])) numberAlpha++;
else if(isdigit(line[i])) numberDigit++;
}
if(numberAlpha+numberDigit>10 && numberDigit>3) printf("%s \n", line);
}
return 0;
}
Now the question is, if it is passible to make it first accepts data and then display only those line which follows the if statment. Now it shows line just after input it.
This code don't count words properly. I don't know if it is wrong on the for or what. Need help.
#include <stdio.h>
#include <stdlib.h>
int count_p(char sentence[100]) {
int i, m = 1;
for (i = 0 ; i < 100 ; i++) {
if (sentence[i] == ' ') {
m += 1;
}
}
return(m);
}
void main() {
char s[100];
int p;
printf("Sentence here: ");
scanf("%s", &s[50]);
p = count_p(sentence);
printf("Words: %d", p);
printf("\n");
}
The %s in scanf stops reading when it found a whitespace. Therefore, ' ' won't appear in s unless it was there as indeterminate value in uninitialized variable.
You can use fgets to read a whole line.
Here is a fixed code that also checks for end of the string.
#include <stdio.h>
#include <stdlib.h>
int count_p(char sentence[100]) {
int i, m = 1;
for (i = 0 ; i < 100 && sentence[i] != '\0'; i++) {
if (sentence[i] == ' ') {
m += 1;
}
}
return(m);
}
int main(void) {
char s[100];
int p;
printf("Sentence here: ");
fgets(s, sizeof(s), stdin);
p = count_p(s);
printf("Words: %d", p);
printf("\n");
return 0;
}
scanf("%s", &s[50]);
Not a correct way to take input and writing at index which is out of bound. Do this instead -
scanf("%99[^\n]", s); // this will read 99 characters and until '\n' is encountered
In main you function call is incorrect -
p = count_p(sentence); // sentence is not declares in main
Call like this -
p = count_p(s); // pass s instead of sentence to function
Also in function count_p change ccondition in for loop as -
size_t i;
size_t len=strlen(s);
for (i = 0 ; i < len ; i++)
You see &s[50] means that you pass a pointer to the 51-th element of s, you then try to access s from the beginning but, the first 50 characters in s were not yet initialized, this leads to undefined behavior.
Also, your loop from 0 to 99 will have the same issue since you might input a string of less than 100 characters, in that case you would be accessing uninitialized data too.
You can fix your program by changing this
scanf("%s", &s[50]);
to
scanf("%99s", s);
and then
for (i = 0 ; i < 100 ; i++) {
to
for (i = 0 ; s[i] != '\0' ; i++) {
because scanf() will append a '\0' to make the array a valid c string, that's also the reason for the "%99s".
Another problem is that, if you want white space characters not to make scanf() stop reading, you need a different specifier, because "%s" stops at the first white space character, this is a suggestion
scanf("%99[^\n]", s);
Or you can do as #MikeCAT suggested and go with fgets(). But be careful with the trailing '\n' in case of fgets().
And finally, altough highly unlikely in this situation, scanf() might fail. To indicate success it returns the number of specifiers actually matched, thus it might indicate partial success too. It's fairly common to see the return value of scanf() ignored, and it's very bad when you have a "%d" specifier for example because then the correspoinding parameter might be accessed before initializing it.
The statement scanf("%s", &s[50]); is in correct in your situation.Since you want to enter a sentence separated by spaces,the correct way of doing it is :
scanf(" %99[^\n]s",sentence);
That will prevent buffer overflow and allow space between words.Also your program does not seem to count words correctly if the sentence has consecutive whitespaces.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int count_p(char *sentence);
void main()
{
char sentence[100];
printf("Sentence here: ");
scanf(" %99[^\n]s",sentence);
int p = count_p(sentence);
printf("Words: %d", p);
printf("\n");
}
int count_p(char *sentence)
{
int len = strlen(sentence);
int x = 0 , wordCount = 0;
for( int n = 0 ; n < len ; n++ )
{
x++;
if( sentence[n] == ' ' )
x = 0;
if( x == 1 )
wordCount++;
}
return wordCount;
}