I am trying to detect whether a string contains only the characters '0' and '1'. This is what I have so far:
while (indexCheck < 32) {
if ((input[indexCheck] != '0') && (input[indexCheck] != '1')) {
printf("not binary ");
indexCheck++;
} else if ((input[indexCheck] = '0') && (input[indexCheck] = '1')) {
indexCheck++;
printf("is binary ");
}
}
I know why it returns "is binary" or "not binary" for every single character in the array, but I don't know how to fix this. I want it to return "is binary" once if the string is only made of '1' and '0', and the opposite if this is false. I'm new to C so all help is appreciated.
Instead of looping manually through the string, you can see if it only contains certain characters by checking to see if strspn() returns the length of the string (By seeing if the index of the value it returns is the 0 terminator at the end of the string):
_Bool is_binary(const char *s) {
if (!s || !*s) {
return 0;
}
return s[strspn(s, "01")] == '\0';
}
I would make a function for this:
int isBinary(const char *input)
{
for (int i = 0; input[i]; ++i)
if (input[i] != '0' && input[i] != '1')
return 0;
return 1;
}
Then you can call the function:
if (isBinary("0001110110101"))
printf("is binary\n");
else
printf("is not binary\n");
https://ideone.com/tKBCbf
You can stop looping through the string the moment you find a character which is neither '0' nor '1'. After the loop is terminated, you check whether or not you've reached the end of the string, i.e. the current character is a null character '\0'
while (*s == '0' || *s == '1') ++s;
if (*s)
puts("not binary");
else
puts("binary");
You can do:
while (indexCheck < 32)
{
if ((input[indexCheck] != '0') && (input[indexCheck] != '1'))
{
break;
}
else
{
indexCheck++;
}
}
if (indexCheck == 32)
printf("is binary ");
else
printf("is not binary ");
Only when it has processed all elements and did not encounter a non 1-or-0 ends the loop with indexCheck == 32 so you can use that to determine what to print.
Note also that your else condition is not needed.
there is a block of code for you with comments.
#include <stdio.h>
#include <stdlib.h>
#define STRING_SIZE 32 // Better to use #define for reusability
// Function prototype
int isBinary(char * testInput);
// Main program
int main(void)
{
// Test inputs
char testInputBinary[33] = "01010101010101010101010101010101";
char testInputNotBinary[33] = "010101010101010101010101010101ab";
// Test & collect results
if (isBinary(testInputBinary))
{
printf("Binary ! \n");
}
else
{
printf("Not binary ! \n");
}
if (isBinary(testInputNotBinary))
{
printf("Binary ! \n");
}
else
{
printf("Not binary ! \n");
}
return EXIT_SUCCESS;
}
int isBinary(char * testInput)
{
int loopIdx = 0; // Loop index
int returnVal = 0; // 0: False, 1: True
// iterate over string
for (loopIdx = 0; loopIdx < STRING_SIZE; loopIdx++)
{
if(testInput[loopIdx] != '0' && testInput[loopIdx] != '1')
{
break;
}
}
// If the loop is not broken, it means all characters are in binary form
if (loopIdx == STRING_SIZE)
{
returnVal = 1;
} // No need to writing else clause since returnVal = 0 at the beginning
return returnVal;
}
int isBinary = 1;
while (input[indexCheck] != '\0')
{
if (input[indexCheck] != '1' && input[indexCheck] != '0')
{
isBinary = 0;
break;
}
++indexCheck;
}
if (isBinary)
{
printf("binary");
}
else
{
printf("not binary");
}
Check each element in string input. If input[index] is not 0 or 1 the flag isBinary becomes 0 and breaks while. And you do not need length of string.
Related
this program checks weather the entered string is palindrome or not . it should be in a way like it should even tell the string is palindrome if there is space or any special character
like messi is a palindrome of iss em
and ronald!o is a palindrome of odlanor
this is the program and for some odd reason it is strucking and not working
#include <stdio.h>
#include <string.h>
int main() {
char palstr[100], ans[100];
printf("enter the string for checking weather the string is a palindrome or not");
scanf("%[^/n]", &palstr);
int ispalin = 1, i = 0, n = 0;
int num = strlen(palstr);
printf("the total length of the string is %d", num);
while (i <= num) {
if (palstr[i] == ' ' || palstr[i] == ',' || palstr[i] == '.' ||
palstr[i] == '!' || palstr[i] == '?') {
i++;
}
palstr[n++] == palstr[i++];
}
int j = num;
i = 0;
while (i <= num) {
ans[j--] = palstr[i];
}
printf("the reverse of the string %s is %s", palstr, ans);
if (ans == palstr)
printf("the string is a palindrome");
else
printf("the string is not a palindrome");
return 0;
}
A few points to consider. First, regarding the code:
if (ans == palstr)
This is not how you compare strings in C, it compares the addresses of the strings, which are always different in this case.
The correct way to compare strings is:
if (strcmp(ans, palstr) == 0)
Second, you should work out the length of the string after you have removed all unwanted characters since that's the length you'll be working with. By that I mean something like:
char *src = palstr, dst = palstr;
while (*src != '\0') {
if (*c != ' ' && *src != ',' && *src != '.' && *src != '!' && *src != '?') {
*dst++ = *src;
}
src++;
}
Third, you have a bug in your while loop anyway in that, if you get two consecutive bad characters, you will only remove the first (since your if does that then blindly copies the next character regardless).
Fourth, you may want to consider just stripping out all non-alpha characters rather than that small selection:
#include <ctype.h>
if (! isalpha(*src) {
*dst++ = *src;
}
Fifth and finally, you don't really need to create a new string to check for a palindrome (though you may still need to if you want to print the string in reverse), you can just start at both ends and move inward, something like:
char *left = &palstr, right = palstr + strlen(palstr) - 1, ispalin = 1;
while (left < right) {
if (*left++ != *right--) {
ispalin = 0;
break;
}
}
There may be other things I've missed but that should be enough to start on.
well, the are so many bugs in this code. I will point them out with comments.
#include <stdio.h>
#include <string.h>
int main() {
char palstr[100], ans[100];
printf("enter the string for checking weather the string is a palindrome or not\n");
scanf("%s", palstr); // your former code won't stop input util Ctrl+D
int ispalin = 1, i = 0, n = 0;
int num = strlen(palstr);
printf("the total length of the string is %d\n", num);
while (i < num) { // < insted of <=
if (palstr[i] == ' ' || palstr[i] == ',' || palstr[i] == '.' ||
palstr[i] == '!' || palstr[i] == '?') {
i++;
continue;// without this, marks still in the string
}
palstr[n++] = palstr[i++]; //should be =
}
palstr[n] = '\0'; //
num = n; // the length might be changed
i = 0;
int j = num-1; // reverse
while (i < num) { //
ans[i++] = palstr[j--]; //
}
ans[i] = '\0'; //
printf("the reverse of the string %s is %s\n", palstr, ans);
//if (ans == palstr) they can never be equal
if (strcmp(ans, palstr)==0)
printf("the string is a palindrome\n");
else
printf("the string is not a palindrome\n");
return 0;
}
i should realize two very similar functions but i am having problems.
I have to read the string "username", this string can only contain letters (upper and lower case) and spaces.
I have to read the string "key", this string can only contain letters (upper and lower case) and numbers.
If the guidelines are not followed, the user must be able to retrieve the input.
Unfortunately, I cannot use special libraries (only stdio and stdlib).
I realized this:
void checkString(char *i){
int cont;
do {
scanf("%s", i);
if (checkStrLen(6, 6, i) != 0) { //function that controls the size of the string (min,max,string)
for(cont=0; cont<6;){
if((i[cont]>='0' && i[cont]<='9')||
(i[cont]>='A' && i[cont]<='Z')||
(i[cont]>='a' && i[cont]<='z')){
cont++;
}else{
printf("Not valid character");
printf("Try again");
}
}
}else{
printf("\nToo large string");
printf("\nTry again");
}
}while(1);
}
I was thinking of doing something similar.
For the first problem I would replace (i[cont]>='0' && i[cont]<='9') with (i[cont]==' ').
the problem is that I don't understand how to get out of the for if I find a forbidden character during the loop.
I was thinking of using a break, but that would get me out of the whole function.
any advice?
PS how does the function look like? can it be okay or is it completely wrong?
I think the do while loop is not necessary here. do the scanf and get user input first then call checkString. Inside checkString keep your if else statement.
char checkString(char *i){
int cont;
if (checkStrLen(6, 6, i) != 0) { //function that controls the size of the string (min,max,string)
for(cont=0; cont<6;){
if((i[cont]>='0' && i[cont]<='9')||
(i[cont]>='A' && i[cont]<='Z')||
(i[cont]>='a' && i[cont]<='z')){
cont++;
}else{
printf("Not valid character");
printf("Try again");
return i;
}
}
}
else{
printf("\nToo large string");
printf("\nTry again");
}
}
#include <stdio.h>
#define MAXSIZE 100
#define SIZELIM 6
#define true 1
#define false 0
// Returns length of string
// If possible, use strlen() from <string.h> instead
int strlen(char *str) {
char i;
for (i = 0; str[i] != 0 && str[i] != '\n'; i++);
return i;
}
// Returns 1 if strings are equal
// If possible, use strcmp() from <string.h> instead
int streq(const char *x, const char *y) {
char chrx = 1, chry = 1, i;
for (i = 0;
chrx != 0 && chry != 0 && chrx == chry;
chrx = x[i], chry = y[i], i++);
return chrx == chry;
}
// Returns 1 if chr is number or letter
// If possible, use isalnum() from <ctype.h> instead
int isalnum(const char chr) {
return (chr >= '0' && chr <= '9' ||
chr >= 'A' && chr <= 'Z' ||
chr >= 'a' && chr <= 'z');
}
// Checks if string contains numbers and letters only
int isvalid(const char *str) {
int valid = true;
for (int i = 0; str[i] != 0 && str[i] != '\n'; i++) {
if (!isalnum(str[i])) {
valid = false;
break;
}
}
return valid;
}
// Main
int main(void) {
char str[MAXSIZE];
for (;;) {
printf("> ");
fgets(str, MAXSIZE, stdin);
if (streq(str, "quit\n"))
break;
if (strlen(str) > SIZELIM || !isvalid(str)) {
if (strlen(str) > SIZELIM)
puts("String too large");
else if (!isvalid(str))
puts("Not a valid string");
puts("Try again"); }
}
return 0;
}
You can code those functions that you cannot import:
int letters_and_spaces(char c)
{
return c == ' ' || C >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z';
}
int letters_and_numbers(char c)
{
return c >= '0' && c <= '9' || C >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z';
}
And to use scanf to read spaces you can't use %s. You could change to:
scanf("%100[^\n]*c", i);
BE CAREFUL: I've put 100, supposing i has enough space for that. It will read up to 100 characters (or as many as the number you put there) or until find the \n.
i'm having real hard time with my code, and my due date is today. i'm given an error "main.c: In function ‘main’:
main.c:186:7: error: expected declaration or statement at end of input
}".
I've been trying for hours to play with the brackets and fix it but with no luck. i'm hoping you could help me fix it, as you are far more experienced than me.
it's basically a simple program that takes input from stdin(might be from keyboard or from a file using redirection) and applies the following:
1)puts a new line between sentences.
2)doesn't print numbers.
3)if inside a bracket, then letters must be capitalized(bold).
4)put's an uppercase on a first character of a sentence.
5)if not in a bracket nor in a beginning of a sentence, then it should make it a lowercase.
notes:
a)there's no limit on the length of the input, and each sentence can be written on several lines(the input).
b)if a dot (.) is inside a brackets, it doesn't make it a new sentence(no need to write a newline).
c)if two dots are given, then it's an empty sentence and should be written like the example.
basically, i just ask you to help me fix my code so it will run, as i've already done all of that(thought of i missed something and you can help me improve it - i will be very glad!)
example:
if given input:
i love to play hockey.. I NEED TO PLAY HOCKEY.. "hockey is life 3333".
the desired output will be:
I love to play hockey.
. I need to play hockey.
.
"HOCKEY IS LIFE"
the code in "temp.h" is:
#define go 0
#define endOfASentence 1
#define isAFirstQuotation 2
#define isASecondQuotation 3
#define inAQuotation 4
#define beginningOfSentence 5
#define middleOfSentence 6
the code in main program is:
#include <stdio.h>
#include <ctype.h>
#include "letters.h"
int checkIfLetter (char a); /*checking if char is a letter */
int checkIfnumber (char a); /*checking if char is a number */
int checkIfUpperCase (char a); /*checking if char is upper case */
int checkIfLowerCase (char a); /*checking if char is lower case */
int checkIfQuotation (char a); /*check if char is a quotation */
int checkIfDot (char a); /*check if char is a dot */
int
main (int argc, const char *argv[])
{
int status = go;
char a;
int beginning = 0; /*if beginning equals 0 it's the beginning of a sentence, if it's 1 then it's the middle of it */
int secondQuote = 0; /*if second quote equals 1, then it's inside of a quotation */
while ((a = getchar ()) != EOF)
{
switch (status)
{
case go:
if (a == '.')
{
status = endOfASentence;
}
else if (a == '"' && secondQuote == '0')
{
status = isAFirstQuotation;
}
else if (a == '"' && secondQuote == '1')
{
status = isASecondQuotation;
}
else if (checkIfLetter (a) == '1' && secondQuote == '1')
{
status = inAQuotation;
}
else if (checkIfnumber (a) == '1')
{
continue;
} /*a number should not be on the output, so we just ignore it and not using it */
else if (checkIfLetter (a) == '1' && beginning == '0')
{
status = beginningOfSentence;
} /*i tried to differentiate between beginning and middle of the sentence using int beginning */
else if (checkIfLetter (a) == '1' && beginning == '1')
{
status = middleOfSentence;
}
case beginningOfSentence:
if (checkIfQuotation (a) && checkIfDot (a)
&& checkIfnumber (a) != 1)
{
if (checkIfUpperCase (a) == '1')
{
printf ("%c", toupper (a));
beginning = 1;
status = go;
}
} break; /*set to upper and return to go */
case middleOfSentence:
if (checkIfQuotation (a) && checkIfDot (a)
&& checkIfnumber (a) != 1)
{
if (checkIfLowerCase (a) == '1')
{
printf ("%c", tolower (a));
status = go;
}
} break;
case endOfASentence:
if (checkIfDot (a) == '1')
{
printf ("%c/n", a);
beginning = 0;
status = go;
}break; /*i tried to append(add) a new line after the dot and to set beginning to 0, to signify that after it's a beginning of a sentence */
case isAFirstQuotation: /*if it's a quotation, continue to the next char and make it upper case as long as it's a lower case, until you get another quotation */
while (checkIfLowerCase (a) == '1')
{
secondQuote == '1';
status = go;
}break;
case isASecondQuotation:
if (checkIfQuotation (a) == '1' && secondQuote == '1')
{
secondQuote = 0;
status = go;
}break;
case inAQuotation:
if (secondQuote == '1' && checkIfLetter (a) == '1')
{
printf ("%c", toupper (a));
status = go;
} break;
}
}
return 0;
}
int checkIfLetter (char a)
{
if (isalpha (a))
{
return 1;
}
else
{
return 0;
}
}
int checkIfnumber (char a)
{
if (isdigit (a))
{
return 1;
}
else
{
return 0;
}
}
int checkIfUpperCase (char a)
{
if (checkIfLetter (a) == '1')
{
if (isupper (a))
{
return 1;
}
else
{
return 0;
}
}
}
int checkIfLowerCase (char a)
{
if (checkIfLetter (a) == '1')
{
if (islower (a))
{
return 1;
}
else
{
return 0;
}
}
}
int checkIfQuotation (char a)
{
if (a == '"')
{
return 1;
}
else
{
return 0;
}
}
int checkIfDot (char a)
{
if (a == '.')
{
return 1;
}
else
{
return 0;
}
}
i don't know how to fix it and i've spent hours on it. would be very grateful if you could help.
i've tried to be very elaborative and to abide the rules
You can try this to see if it produces the desired results.
Characters that are not letters, space, newline or dot are rejected at the top of the while and all letters are set to lower case.
Then the choice is to print one upper case letter at the start of the sentence or all upper case inside double quotes.
There are no breaks as oneUpper needs to fall through to allUpper. allUpper needs to fall through to default.
getchar returns an int so int a instead of char a
#include <stdio.h>
#include <ctype.h>
#define oneUpper 1
#define allUpper 2
int main (int argc, const char *argv[])
{
int status = oneUpper;
int a;
while ( EOF != (a = getchar ()))
{
//discard non letter except space, newline and .
if ( !isalpha ( a) && a != ' ' && a != '\"' && a != '.') {
continue;
}
//set all to lower and let oneUpper or allUpper do the rest.
a = tolower ( a);
switch (status)
{
case oneUpper:
if ( a == ' ' || a == '\n') {
putchar ( a);//print leading space and continue
continue;
}
case allUpper:
a = toupper ( a);
default:
putchar ( a);
if ( a == '\"') {
if ( status == allUpper) {
status = 0;//turn all upper off
}
else {
status = allUpper;//turn all upper on
}
}
if ( status == oneUpper) {
status = 0;//after printing one upper turn it off
}
if ( a == '.') {
if ( status != allUpper) {
putchar ( '\n');
status = oneUpper;//after a . turn one upper on
}
}
}
}
return 0;
}
I am trying out a program which translates user input based on the below rules:
If the character is a letter, it must be printed in upper case.
If the character is a number (0-9), an asterisk (*) must be printed instead.
If the character is a double quote ("), a single quote (') must be printed instead.
If the character is the backslash "\" then it is skipped (not printed), and the next character is printed without any modifications.
Otherwise, the character is printed as-is.
MyCode
#include <stdio.h>
void lowertoupper(char lower)
{
char upper;
if(lower >= 'a' && lower <= 'z'){
upper = ('A' + lower - 'a');
}
else{
upper = lower;
}
printf("%c",upper);
}
int main(void) {
char chara;
printf("please enter");
while(scanf(" %c", &chara)!= EOF) {
if ((chara>='a' && chara<='z')||(chara>='A' && chara<='Z'))
{
lowertoupper(chara);
}
else if (chara>=0 && chara<=9)
{
printf("*");
}
else if (chara=='"')
{
printf("'");
}
else if (chara=="\\")
{
}
else {
printf("%c",chara);
}
}
}
My questions
This doesn't as expected. What conditions am I missing here.
How can I satisfy the condition 4 without using any built in function.
int noChange = 0; /* Added */
while(scanf(" %c", &chara) == 1) { /* Modified */
if(noChange == 1) { /* Added */
printf("%c",chara); /* Added */
noChange = 0; /* Added */
} /* Added */
else if ((chara>='a' && chara<='z')||(chara>='A' && chara<='Z')) /* Modified */
{
lowertoupper(chara);
}
else if (chara >= '0' && chara <= '9') /* Modified */
{
printf("*");
}
else if (chara=='"')
{
printf("'");
}
else if (chara=='\\') /* Modified */
{
noChange = 1; /* Added */
}
else {
printf("%c",chara);
}
}
Working demo here
This also works, comparing chara stores the ascii value, so ascii value of '0' is not 0.
#include <stdio.h>
int main() {
char chara = '\0';
while(scanf("%c", &chara) == 1) {
if ( chara>='a' && chara<='z' ) printf("%c",'A' + (chara - 'a'));
else if (chara >= '0' && chara <= '9') printf("%c",'*');
else if (chara=='"') printf("%c",'\'');
else if (chara=='\\') ;
else printf("%c",chara);
}
}
Your test for digits is problem. The digit characters are '0' through '1', whose actual value depends on the local charset but are never 0 through 9.
Well there is program doing it's function right, but I am trying to make it check, if user-entered value is number(doesn't contain letters or signs). So basically I am using if with isdigit or '/0' condition. Program compiles properly, but I am getting error, when entering less than 3 types(even numbers...). What is wrong with it? Only thing I need is to skip loop when number is 0-999 and re-ask while it isn't, or if it is not number.
char x[5];
bool isgood;
int tab[20][2],i=0,a;
do
{
isgood = TRUE;
printf("Write a where 0<a<1000\n");
scanf("%4s", x);
for (int j = 0; j < 4; j++)
{
if (isdigit(x[j])==0 || x[j]!='/0') isgood = FALSE;
}
a = atoi(x);
if (a<1000 && isgood == TRUE) break;
} while (1);
Wrong:
Your boolean-logic
Your null-character
Calling atoi when isgood is FALSE
Change this:
isdigit(x[j])==0 || x[j]!='/0'
To this:
isdigit(x[j])==0 && x[j]!='\0'
And this:
a = atoi(x);
if (a<1000 && isgood == TRUE) break;
To this:
if (isgood == TRUE)
{
a = atoi(x);
if (0<a && a<1000)
break;
}
Here is a far more simple way of doing the whole thing:
int x;
char c;
do
{
printf("Write a where 0<a<1000\n");
if (scanf("%d",&x) == 0)
scanf("%c",&c);
else if (0<x && x<1000)
break;
}
while (1);