I have to submit this code as a solution. My code runs perfectly for the given test cases, but I am not able to submit as the code fails one of the tests in the solver. Please help if you can. Any help is appreciated.
Gift Article with Digits
Many customers liked the gift articles with digits inscribed on them and they started buying them for gifting for Birthdays and anniversaries. One customer came to purchase a gift for his mom's 25th wedding anniversary and another customer came to purchase a gift for his son's 18th Birthday. They were disappointed to see only single digits inscribed on the gift items.
Seeing the craze for this kind of gift items, Nisha gave a bulk order for gift items with 2 digit numbers inscribed on them. The parcel arrived when she was busy and her 4 year old son started arranging the newly arrived items in the rack for display. But he has placed all items upside down. She needs to change the orientation of the items.
But to her surprise, she found that some 2-digit numbers were valid when read both ways. [Eg. 68 read upside down would be 89 which is also a valid number] Help Nisha in identifying all such 2 digit numbers.
TestCase
Input 1
18
Output 1
YES
Input 2
46
Output 2
NO
Input 3
a4
Output 3
Invalid Input
C code:
#include<stdio.h>
#include<ctype.h>
#include<string.h>
int main()
{
char str[2];
scanf("%s",str);
int flag=0;
if (strlen(str)!=2)
{
flag=2;goto label;
}
else if (str[1]=='0')
{
flag=1;goto label;
}
for(int i=0;i<2;i++)
{
if(isdigit(str[i]))
{
if((str[i]!='0')&&(str[i]!='1')&&(str[i]!='6')&&(str[i]!='8')&&
(str[i]!='9'))
{
flag=1;break;
}
}
else
{flag=2;break;}
}
label:
if (flag==0) printf("YES");
else if (flag==1) printf("NO");
else if (flag==2) printf("Invalid Input");
return 0;
}
The output after evaluation is as follows:
The program's output is incorrect e.g. for 4a, because you break out of the loop after checking the first digit.
The program's answer is NO when it should be Invalid Input.
the main problem with the code is the following two lines
char str[2];
scanf("%s",str);
When the scanf() input/conversion specifier is "%s" then the function will append a NUL ('\0') char to the input AND the input is not stopped until a white space character is encountered.
White space: space, tab, newline sequence
Therefore, when using the '%s" input/conversion specifier there are two considerations:
the input buffer must be 1 char longer that the max allowed number of input characters
the MAX_CHARACTERS modifier must be used, that is 1 less than the length of the input buffer.
Therefore, those two lines should be:
char str[3]; // allows room for 2 characters plus NUL terminator
scanf("%2s",str); // only allow user to input two characters
however, there are some other problems with the code.
This line:
if (strlen(str)!=2)
does not allow for when there is only a single digit I.E. 1...9 inclusive.
it is a very poor programming practice to use the goto + label sequence. It invariable results in 'spaghetti' code.
this code block:
else if (str[1]=='0')
{
flag=1;
goto label;
}
is not correct as it rejects 10, 20, 30, 40, 50, 60, 70, 80, 90. Note: in C, an array index is in the range 0...(one less than the number of entries in the array) Note: '0' is 0x30 in hex and the NUL terminator is 0x00 in hex.
This line:
for( int i=0; i<2; i++ )
is making the assumption that all the 'ages' are 2 digit numbers. That excludes the ages 1...9 inclusive. Suggest:
for( size_t i=0; i<=strlen(str); i++ )
Note: strlen() returns a size_t, not an int and returns the index to the NUL char
flag = 2; // initialize to indicate invalid input
if( strlen( str ) )
{ // then some characters entered by user
for( size_t i=0; i<strlen( str ); i++ )
{
... // check for invertible digit
... // check for non digit
}
}
switch( flag )
{
case 0:
printf( "YES\n" );
break;
case 1:
printf( "NO\n" );
break;
default:
printf( "Invalid Input\n" );
break;
} // end switch
// Note: on modern C compilers,
// when the returned value from 'main()' is always 0,
// then no 'return 0;' statement actually needed
return 0;
} // end function: main
However, the above code snippet does not handle when the user input contains 1 invertible digit and 1 non invertible digit nor when any of the user input is not a digit. I'll let you supply the appropriate logic. The above should get you started in the right direction.
You can try the below code!
#include<stdio.h>
#include<string.h>
void main(){
char str[2];
int a,b;
scanf("%s",str);
a=str[0];
b=str[1];
if(strlen(str)!=2)
printf("Invalid Input");
else if(str[0]=='0')
printf("NO");
else if((a>47&&a<58)&&(b>47&&b<58))
{
if(((str[0]=='1')||(str[0]=='6')||(str[0]=='8')||(str[0]=='9'))&&((str[1]=='1')||(str[1]=='6')||(str[1]=='8')||(str[1]=='9')))
printf("YES");
else
printf("NO");
}
else
printf("Invalid Input");
}
Related
Basically, my code is supposed to encrypt a sentence(or word) by taking out all the even numbered index values(starting from 0) and the odd numbered index values and placing the even index values before the odd index values.
For example, a word like "test" (0)t(1)e(2)s(3)t should be printed as (0)t(2)s(1)e(3)t or "tset". There aren't supposed to be any numbers printed, I just used them to show the odd and even index values.
My code works sometimes, depending on where it is run. I seem to be getting differing results between code blocks and an online compiler I tried. I suspect there must be a larger issue to blame for this inconsistency. Can anyone help me to see what I'm doing wrong so I can finally understand and rectify my errors?
I have tried using one counter to input both even and odd index values into one array but I was having errors with that as well so I decided to put them into separate arrays and then use strcat to combine them. Is there a way to make it work with the method I've shown in my code or should I go back to the previous method?
#include <stdio.h>
#include <string.h>
#define SIZE 1000
int main()
{
char message[SIZE];
char even[SIZE];
char odd[SIZE];
int length,j=0;
printf("Enter a word or sentence.\n");
fgets(message,SIZE,stdin);
printf("Your message is: %s\n",message);
message[strcspn(message, "\n")] = 0;
length=strlen(message);
printf("The length of the message is: %d\n",length);
for(int i=0;i<length;i+=2){
even[i/2]=message[i];
// printf("%c\n",even[i/2]);
}
for(int i=1;i<length;i+=2){
odd[j]=message[i];
j++;
}
printf("The even letters are: %s\n",even);
printf("The odd letters are: %s\n",odd);
strcat(even,odd);
printf("%s",even);
/*printf("\nFInalyy.");
for(i=0;i<=count;i++)
for(j=i+1;j<=count;j++){
if(strcmp(allmessages[i],allmessages[j])>0){
strcpy(temp,allmessages[i]);
strcpy(allmessages[i],allmessages[j]);
strcpy(allmessages[j],temp);
}
}
printf("The original messages in alphabetical order are: ");
for(i=0;i<=count;i++)
puts(allmessages[i]);*/
return 0;
}
It works perfectly when I type in words like "test" or "sentence". Sometimes I type in sentences like "this is a test sentence" and it would work perfectly then one time it would print out some random garbage letters along with the encrypted sentence. I would like to know how to fix this and to understand why it works perfectly with the same entry a few times then just stops. I used https://www.onlinegdb.com/online_c_compiler to test it the last few times so my results are based on that.
Successful Result:
Unsuccessful Result using the same entry:
You can take a slightly shorter approach by simply using two indexes to build your encrypted string (like evenstart and oddstart) based on the total length of the message entered by the user. evenstart = 0; and oddstart = (msglen + 1) / 2;
Then just loop over the characters in the message entered by the user writing even characters at encrypt[evenstart++] and odd characters at encrypt[oddstart++]. (don't forget to nul-terminate encrypt if you will be using it as a string for output purposes.
Putting it together you could do:
#include <stdio.h>
#include <string.h>
#define MAXC 1024
int main (void) {
char message[MAXC],
encrypt[MAXC];
size_t len, evenstart = 0, oddstart;
fputs ("enter message: ", stdout);
if (!fgets (message, MAXC, stdin)) { /* validate message entered */
fputs ("(user canceled input)\n", stdout);
return 1;
}
message[(len = strcspn(message, "\r\n"))] = 0; /* trim '\n', get len */
oddstart = (len + 1) / 2; /* get oddstart (add 1 before divide) */
for (size_t i = 0; i < len; i++) /* loop over each char */
if (i & 1) /* if odd, write char at oddstart */
encrypt[oddstart++] = message[i];
else /* if even, write at evenstart */
encrypt[evenstart++] = message[i];
encrypt[len] = 0; /* nul-terminate */
printf ("message : '%s'\nencrypt : '%s'\n", message, encrypt);
}
(note: you can use i % 2 to check even/odd if you like, or simply i & 1 -- in binary, if the ones-bit is 1 it's odd, otherwise its even -- up to you)
Example Use/Output
$ ./bin/encrevenodd
enter message: tes
message : 'tes'
encrypt : 'tse'
$ ./bin/encrevenodd
enter message: test
message : 'test'
encrypt : 'tset'
$ ./bin/encrevenodd
enter message: tests
message : 'tests'
encrypt : 'tsset'
$ ./bin/encrevenodd
enter message: my dog has fleas
message : 'my dog has fleas'
encrypt : 'm o a laydghsfes'
Look things over and let me know if you have questions.
Strings in C are terminated by the null byte ('\0' or ascii value 0) just so it knows where the string ends. Since the even and odd character arrays were not terminated by the null byte, strcat does not know when to stop appending characters. So the garbage values you see is because strcat keeps appending characters until you luckily find a 0 in memory.
Strings in C do not know their length, they're just pointers. Strings must be terminated with a null character in order for functions like printf and strlen to know when to stop.
char even[SIZE];
char odd[SIZE];
At this point even and odd both contain whatever garbage was in memory at that time.
for(int i=0;i<length;i+=2){
even[i/2]=message[i];
}
for(int i=1;i<length;i+=2){
odd[j]=message[i];
j++;
}
Now the beginning of odd and even have been filled in, but they were not null terminated.
printf("The even letters are: %s\n",even);
printf("The odd letters are: %s\n",odd);
These will start at where even and odd point, print the characters you've put in there, and then keep on printing whatever garbage was in memory until they happen to hit a null character.
The fix is to either zero out the memory with memset.
memset(even, '\0', SIZE);
memset(odd, '\0', SIZE);
Or ensure that even and odd are null terminated once you're done with them.
for(i=0;i<length;i+=2){
even[i/2]=message[i];
}
even[i/2] = '\0';
for(i=1;i<length;i+=2){
odd[j]=message[i];
j++;
}
odd[j] = '\0';
Side note, even and odd loops can be done with the same technique.
for( i=0,j=0; i<length; i+=2,j++ ) {
even[j]=message[i];
}
even[j] = '\0';
for( i=1,j=0; i<length; i+=2,j++ ) {
odd[j]=message[i];
}
odd[j] = '\0';
Then we can observe that the only difference is where we start reading message. That means we can put this in a function and always remember to null terminate the result.
void copy_every_other_character(const char *src, char *dst) {
int i,j,length = 0;
length = strlen(src);
for( i=0,j=0; i<length; i+=2,j++ ) {
dst[j] = src[i];
}
dst[j] = '\0';
}
copy_every_other_character(message, even);
copy_every_other_character(message+1, odd);
Adding 1 to message means copy_every_other_character will get a pointer to the second character of message and go on from there. If message is 01234 it will see 1234.
How can I split character and variable in 1 line?
Example
INPUT
car1900food2900ram800
OUTPUT
car 1900
food 2900
ram 800
Code
char namax[25];
int hargax;
scanf ("%s%s",&namax,&hargax);
printf ("%s %s",namax,hargax);
If I use code like that, I need double enter or space for make output. How can I split without that?
You should be able to use code like this to read one name and number:
if (scanf("%24[a-zA-Z]%d", namax, &hargax) == 2)
…got name and number OK…
else
…some sort of problem to be reported and handled…
You would need to wrap that in a loop of some sort in order to get three pairs of values. Note that using &namax as an argument to scanf() is technically wrong. The %s, %c and %[…] (scan set) notations all expect a char * argument, but you are passing a char (*)[25] which is quite different. A fortuitous coincidence means you usually get away with the abuse, but it is still not correct and omitting the & is easy (and correct).
You can find details about scan sets etc in the POSIX specification of scanf().
You should consider reading a whole line of input with fgets() or POSIX
getline(), and then processing the resulting string with sscanf(). This makes error reporting and error recovery easier. See also How to use sscanf() in loops.
Since you are asking this question which is actually easy, I presume you are somewhat a beginner in C programming. So instead of trying to split the input itself during the input which seems to be a bit too complicated for someone who's new to C programming, I would suggest something simpler(not efficient when you take memory into account).
Just accept the entire input as a String. Then check the string internally to check for digits and alphabets. I have used ASCII values of them to check. If you find an alphabet followed by a digit, print out the part of string from the last such occurrence till the current point. And while printing this do the same with just a slight tweak with the extracted sub-part, i.e, instead of checking for number followed by letter, check for letter followed by digit, and at that point print as many number of spaces as needed.
just so that you know:
ASCII value of digits (0-9) => 48 to 57
ASCII value of uppercase alphabet (A-Z) => 65 to 90
ASCII value of lowercase alphabets (a-z)
=> 97 to 122
Here is the code:
#include<stdio.h>
#include<string.h>
int main() {
char s[100];
int i, len, j, k = 0, x;
printf("\nenter the string:");
scanf("%s",s);
len = strlen(s);
for(i = 0; i < len; i++){
if(((int)s[i]>=48)&&((int)s[i]<=57)) {
if((((int)s[i+1]>=65)&&((int)s[i+1]<=90))||(((int)s[i+1]>=97)&&((int)s[i+1]<=122))||(i==len-1)) {
for(j = k; j < i+1; j++) {
if(((int)s[j]>=48)&&((int)s[j]<=57)) {
if((((int)s[j-1]>=65)&&((int)s[j-1]<=90))||(((int)s[j-1]>=97)&&((int)s[j-1]<=122))) {
printf("\t");
}
}
printf("%c",s[j]);
}
printf("\n");
k = i + 1;
}
}
}
return(0);
}
the output:
enter the string: car1900food2900ram800
car 1900
food 2900
ram 800
In addition to using a character class to include the characters to read as a string, you can also use the character class to exclude digits which would allow you to scan forward in the string until the next digit is found, taking all characters as your name and then reading the digits as an integer. You can then determine the number of characters consumed so far using the "%n" format specifier and use the resulting number of characters to offset your next read within the line, e.g.
char namax[MAXNM],
*p = buf;
int hargax,
off = 0;
while (sscanf (p, "%24[^0-9]%d%n", namax, &hargax, &off) == 2) {
printf ("%-24s %d\n", namax, hargax);
p += off;
}
Note how the sscanf format string will read up to 24 character that are not digits as namax and then the integer that follows as hargax storing the number of characters consumed in off which is then applied to the pointer p to advance within the buffer in preparation for your next parse with sscanf.
Putting it altogether in a short example, you could do:
#include <stdio.h>
#define MAXNM 25
#define MAXC 1024
int main (void) {
char buf[MAXC] = "";
while (fgets (buf, MAXC, stdin)) {
char namax[MAXNM],
*p = buf;
int hargax,
off = 0;
while (sscanf (p, "%24[^0-9]%d%n", namax, &hargax, &off) == 2) {
printf ("%-24s %d\n", namax, hargax);
p += off;
}
}
}
Example Use/Output
$ echo "car1900food2900ram800" | ./bin/fgetssscanf
car 1900
food 2900
ram 800
I am taking in 10 numbers from the user (user enters them at a prompt, and the numbers are separated by commas, as so: 245645, -243, 4245). How can I put these elements into an array? As shown below, I have used scanf which does not work as I had hoped. Any suggestions would be appreciated.
//User will pass ten numbers, separated by commas. This is to be put into an array.
#include <stdio.h>
int main ()
{
int A[10]; // array to contain in users input.
printf("Enter your numbers: ");
scanf("%d", &A[10]);
return 0;
}
You have to consume the comma as well in scanf:
for(int i=0; i<10; i++) { /* for each element in A */
if(0==scanf("%d,", &A[i])) { /* read a number from stdin into A[i] and then consume a commma (if any) */
break; /* if no digit was read, user entered less than 10 numbers separated by commas */
/* alternatively error handling if fewer than 10 is illegal */
}
}
I won't write the whole thing for you.
But I can definitely help.
One of the ways to do that will be:
Get a string that contains 10 comma-separated numbers: fgets() may be?
Validate the string, trim white-spaces as well, makes life easier
Pick out a number from string: strtol() may be?
Search for a ',' character in the string, and set pointer to the next index after ',': strchr() may be?
Repeat steps 3 and 4 for a total of 10 times (from here, 9 times actually)
Print the numbers
The code below would do half of your job. The only remaining part would be to get string from user and validate it.
The intention to have a string declared and initialised upfront is to put more emphasise on actual parsing of data which appear complicated to beginners (no offence).
Before we look at the code below, lets read a few things first.
You might want to take a look at the man page for strtol() function
You might want to take a look at the man page for fgets() function, which is not used in the code below, but you may end-up using it to achieve step 1.
I already concede the fact that this may not be the best way to achieve it, and I would happily agree that this code below can be made better in thousand ways by adding various error check, but I leave that to you to explore and implement.
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main(void)
{
int i = 0, j = 0;
char *Str = "1,11,21,1211,111221,312211,1234,4321,123,789";
char *ptr;
long ret;
long array[10] = { [0 ... 9] = 0 };
// So, lets assume step 1 and 2 are taken care of.
// Iterate though the data for 10 times
for(i = 0; i < 10; i++)
{
ret = strtol(Str, &ptr, 10);
// Check if its a number
if(ret != 0)
{
// Its is a number!
// Put it in the array
array[j] = ret;
// Increment the index so that next number will not over-write the existing one
j++;
// Find the next ',' in the string
Str = strchr(Str, ',');
if(Str == NULL)
{
// Handle this condition that there are no more commas in the string!
break;
}
// Assuming that the ',' is found, increment the pointer to index next to ','
Str++;
}
}
// Print the array
for(i = 0; i < j; i++)
printf("%ld\n", array[i]);
}
This prints the following output:
1
11
21
1211
111221
312211
1234
4321
123
789
Hope I have got you started, Good luck.
I need to get a valid number from the user between 0-9 without duplicates.
The valid number can have any number of digit, from 1 to 10.
If the user type "space" or any kind of char, then the input is invalid.
My algorithm :
1) Create an array of char in size of 10, then initialize all cells to '0'.
2) For every char that reads from the user, check if the char actually between 0-9.
2.1) If true: count the respectively cell number +1.
2.2) Else "error".
2.3) If I get to a cell that already has +1, means this number already exist, then "error".
Now a few questions about my idea:
1) Is there any better\easy algorithm to do that?
2) The user doesn't type char by char, means I can get an infinite char length, so where do I store everything?
The answer to 2) is: you don't store the characters at all, you process them one by one. You only need storage to remember which digits you have already seen. I'd do it like this:
#include <stdio.h>
#include <ctype.h>
int main(void)
{
char seen[10] = { 0 };
int c, loops;
for (loops = 0; (c = getchar()) != EOF && loops < 10; ++loops)
{
if (!isdigit(c)) {
printf ("Not a digit: %c\n", c);
break;
}
c -= '0';
if (seen[c]) {
printf ("Already seen: %d\n", c);
break;
}
seen[c] = 1;
}
return 0;
}
Try to modify this program as an exercise: reduce the storage requirements of the seen[] array. As written it uses one byte per digit. Make the program use only one bit per digit.
(Hi guys. I tried searching for the problem I'm having and can't seem to find the solution so far. I'm totally new to programming and am learning C currently, but I am a complete noob so I apologize in advance if I'm making a dumb mistake.)
Here's the problem: Im tryna scan 4 integers and print their values using a while loop. The problem is, the numbers are being printed as crazy long numbers not as the ints that are input. I tried scanning and printing a single int and it printed fine but once I use multiple ints, it starts screwing aroud.
Here's my code:
#include <stdio.h>
int main()
{
int i, n1,n2,n3,n4;
printf("Enter 4 numbers.");
for(i=0;i<4;i++)
{
printf("\n\nEnter number %d: ", i+1);
scanf("%d,%d,%d,%d", &n1,&n2,&n3,&n4);
printf("%d,%d,%d,%d", n1,n2,n3,n4);
}
}
Two things:
the input format given in scanf() should match exactly to the input value for a successful scan. [You need to have ,s in your input]
Always check for the success of scanf() to ensure proper scanning of value. scanf() returns the number of items successfully matched and scanned.
So, you should change your code to something like,
if ( scanf("%d,%d,%d,%d", &n1,&n2,&n3,&n4) == 4)
{
// use n1, n2, n3, n4
}
else
//don't use them, return some error.
Note: Always initialize local variables. Many a time it will save you from the undefined behaviour of read-before-write scenario.
Also, [maybe?] the for loop is not required, as you're scanning all the four numbers at a time.
When you have scanf("%d,%d,%d,%d", &n1,&n2,&n3,&n4);
you must give your input as say
1,2,3,4( commas are needed)
And you said you want to read 4 numbers and you have a scanf that gets the 4 numbers. So there is no need for a loop here. If you want to loop get one number each time inside the loop.
You are looping 4 times, expecting to read 4 numbers in each loop...
Generally speaking, scanf() is a poor tool for parsing any kind of input that might not match the expected format -- and nothing is as fickle as user input. I usually advise reading in whole lines of input (via fgets()), and then parsing them in-memory as appropriate (which, in this case, would probably mean using strtol() and checking how much of the input string was parsed via its second parameter).
This, for example, is much more robust:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#define LINELEN_MAX 100
int main()
{
int i;
char input[ LINELEN_MAX ];
char * current;
char * end;
while ( 1 )
{
// whitespaces or commas do not matter,
// and neither does the amount of numbers.
puts( "Enter numbers, or 'q' to quit." );
if ( fgets( input, LINELEN_MAX, stdin ) == NULL )
{
puts( "Error on read." );
return EXIT_FAILURE;
}
if ( *input == 'q' )
{
puts( "Quitting." );
return EXIT_SUCCESS;
}
if ( input[ strlen( input ) - 1 ] != '\n' )
{
puts( "Line exceeded maximum width." );
return EXIT_FAILURE;
}
current = input;
end = input;
while ( *current )
{
if ( !isdigit( *current ) )
{
// skip non-digits
++current;
}
else
{
// parse 1..n digits and print
printf( "%ld\n", strtol( current, &end, 10 ) );
current = end;
}
}
}
}
One reason may be that all your values are being printed onto the same line without any space between them.
Basically you are printing 4 numbers continuously in one line which makes it look like one big number.
I advise you to add a new line format specifier.(If you are a newbie, then you might not understand this, so here are some links that may be useful)
http://www.codingunit.com/printf-format-specifiers-format-conversions-and-formatted-output
There is also the problem that you are reading 4 numbers 4 times , that is you are reading 16 variables in total. For this code , you actually don't need a for loop.