Im trying to read a char and number with the following:
char c;
char plus = '+';
int last;
if(scanf("%c%d",&c,&last)!=2 || last<0){
printf("fail\n");
return 1;
};
//trying to test it
if(plus==c){
// code
}
But when I start the program, and type + 100 it throws "fail", as scanf wasn't successful. But if I just type 100 it works. Why does "fail" get printed when there are one char (+) and number (100) and why it doesn't if I just type number.
Your code is fine except for a ; try this it works :
#include <stdio.h>
int main( )
{
test();
}
int test()
{
char c;
char plus = '+';
int last;
if ( scanf( "%c%d", &c, &last ) != 2 || last < 0 )
{
printf( "fail\n" );
return 1;
} ///////////// YOU HAD UNNEEDED ; HERE
else
{
printf( "\nyou entered:\n%c,%d", c, last );
getchar( );
}
//trying to test it
if ( plus == c )
{
// code
}
}
Related
I have written this code for finding the character with the minimum frequency.
So, giving in input "Hi, how is the weather todayy Dori", the output should be
The letter with the minimum frequency is āsā and the frequency is 1.
But it shows
How to remove the that coma what is my mistake here
#include<stdio.h>
#include <string.h>
#include <ctype.h>
#define MAX 1000
int main()
{
char str[MAX];
int fre[MAX],i,q,r,co=0,num;
printf("The string : ");
gets(str);
for(q=0;str[q];q++);
r=num=q;
for(i=0;i<num;i++)
{
fre[i]=num;
co=1;
if(str[i])
{
for(q=i+1;q<num;q++)
{
if(tolower(str[i]) == tolower(str[q]))
{
{
co++;
str[q]='\0';
}
}
fre[i]=co;
if(co<=r)
r=co;
}
}
}
printf("The letter with the minimum frequency is");
for(q=0;q<num;q++)
{
if(fre[q]==r)
{
printf(" '%c' ",str[q]);
}
}
printf("and the frequency is %d \n ",r);
return 0;
}
For starters the function gets is unsafe and is not supported by the C Standard. Instead use the standard C function fgets.
As an entered string in general can be very big while letters in the string converted to the lower case can be in the range of ['a', 'z'] then there is no sense to declare such a big array as the array fre declared like.
int fre[MAX];
As you already included the header <string.h> then there is no sense manually to calculate the length of the entered string.
for(q=0;str[q];q++);
To exclude non-letters characters from counting you can use the standard C function isalpha declared in the header <ctype.h>.
Pay attention to that in general the entered string can have no letters.
Here is a demonstrative program that shows how your approach can be implemented.
#include <stdio.h>
#include <ctype.h>
int main(void)
{
enum { MAX = 1000 };
char s[MAX];
size_t frequency[ 'z' - 'a' + 1] = { 0 };
const size_t N = sizeof( frequency ) / sizeof( *frequency );
printf( "The string: " );
if ( fgets( s, MAX, stdin ) )
{
for ( const char *p = s; *p; ++p )
{
if ( isalpha( ( unsigned char )*p ) )
{
++frequency[tolower( ( unsigned char )*p ) - 'a'];
}
}
size_t min = 0;
for ( size_t i = 0; i < N; i++ )
{
if ( frequency[i] != 0 && ( min == 0 || frequency[i] < min ) )
{
min = frequency[i];
}
}
if ( min == 0 )
{
puts( "There ie no letters in the entered string." );
}
else
{
printf( "The letter with the minimum frequency is: " );
for ( size_t i = 0; i < N; i++ )
{
if ( frequency[i] == min ) printf( "%c ", ( int )('a' + i ) );
}
printf( "\nand the frequency is %zu\n ", min );
}
}
return 0;
}
The program output might look like
The string: Hi, how is the weather todayy Dor
The letter with the minimum frequency is: s
and the frequency is 1
There's really no reason to read more than one character at a time. In general, that's a good pattern to try and follow. eg:
#include <stdio.h>
#include <string.h>
#include <limits.h>
#include <ctype.h>
int main(void)
{
int c;
int fre[26] = {0};
printf("The string : ");
while( (c = getchar()) != EOF ) {
putchar(c);
if( isalpha(c) ) {
fre[tolower(c) - 'a'] += 1;
}
}
printf("The letter with the minimum frequency is");
int idx = 0;
int m = INT_MAX;
for( int q = 0; q < 26; q++ ) {
if( fre[q] > 0 && fre[q] < m ) {
idx = q;
m = fre[q];
}
}
printf(" '%c', with frequency %d\n", idx + 'a', fre[idx]);
return 0;
}
I need to replace several characters with one (depending if their count is even or odd). If it's even i should replace + with P, if it's odd with p.
Input: kjlz++zux+++
while(p[i])
{
j=i;
k=i;
length=strlen(p);
if(p[i]=='*')
{
position=i;
}
printf("Position is: %d", position);
while(p[j]=='*')
{
counter++;
j++;
}
}
Output: kjlzPzuxp
Im not sure how to remove several characters I know how to input one.
Basically you can leave the text variable intact until you find a +. In that case you start counting how many consecutive plusses there are. Once you know this, it can be decided if you should add a letter P or p. Keep a separate index to write back to your text variable! Otherwise it would start writing to the wrong index after 2 or 3 plusses are found, try to figure out why ;).
#include <stdio.h>
#include <stdlib.h>
int main (void)
{
char text[] = "kjlz++zux+++";
int len = sizeof(text) / sizeof(text[0]);
int index = 0, count = 0;
for(int i = 0; i < len; i++)
{
if(text[i] == '+')
{
count = 0;
while(text[i] == '+') i++, count++;
i--;
text[index++] = count % 2 ? 'p' : 'P';
}
else
{
text[index++] = text[i];
}
}
text[index] = 0;
printf(text);
}
You could allocate space for the text variable with malloc so that you can use realloc afterwards to shrink the array to the size of the output text. This way some memory is saved, this is especially important when you start working with bigger chunks of data.
If I have understood correctly you do not know how to implement a corresponding function.
It can look the following way as it is shown in the demonstrative program.
#include <stdio.h>
char * replace_pluses( char *s )
{
const char plus = '+';
const char odd_plus = 'p';
const char even_plus = 'P';
char *dsn = s;
for ( char *src = s; *src; )
{
if ( *src == plus )
{
int odd = 1;
while ( *++src == plus ) odd ^= 1;
*dsn++ = odd ? odd_plus : even_plus;
}
else
{
if ( dsn != src ) *dsn = *src;
++dsn;
++src;
}
}
*dsn = '\0';
return s;
}
int main(void)
{
char s[] = "kjlz++zux+++";
puts( s );
puts( replace_pluses( s ) );
return 0;
}
The program output is
kjlz++zux+++
kjlzPzuxp
Or you can write a more generic function like this
#include <stdio.h>
char * replace_odd_even_duplicates( char *s, char c1, char c2, char c3 )
{
char *dsn = s;
for ( char *src = s; *src; )
{
if ( *src == c1 )
{
int odd = 1;
while ( *++src == c1 ) odd ^= 1;
*dsn++ = odd ? c2 : c3;
}
else
{
if ( dsn != src ) *dsn = *src;
++dsn;
++src;
}
}
*dsn = '\0';
return s;
}
int main(void)
{
char s[] = "kjlz++zux+++";
puts( s );
puts( replace_odd_even_duplicates( s, '+', 'p', 'P' ) );
return 0;
}
I'm trying to split a string into chunks of 6 using C and I'm having a rough time of it. If you input a 12 character long string it just prints two unusual characters.
#include <stdio.h>
#include <string.h>
void stringSplit(char string[50])
{
int counter = 0;
char chunk[7];
for (unsigned int i = 0; i < strlen(string); i++)
{
if (string[i] == ' ')
{
continue;
}
int lastElement = strlen(chunk) - 1;
chunk[lastElement] = string[i];
counter++;
if (counter == 6)
{
printf(chunk);
memset(chunk, '\0', sizeof chunk);
counter = 0;
}
}
if (chunk != NULL)
{
printf(chunk);
}
}
int main()
{
char string[50];
printf("Input string. \n");
fgets(string, 50, stdin);
stringSplit(string);
return(0);
}
I appreciate any help.
Your problem is at
int lastElement = strlen(chunk) - 1;
Firstly, strlen counts the number of characters up to the NUL character. Your array is initially uninitialized, so this might cause problems.
Assuming your array is filled with NULs, and you have, let's say, 2 characters at the beginning and you are looking to place the third one. Remember that your 2 characters are at positions 0 and 1, respectively. So, strlen will return 2 (your string has 2 characters), you subtract one, so the lastElement variable has the value 1 now. And you place the third character at index 1, thus overwriting the second character you already had.
Also, this is extremely inefficient, since you compute the number of characters each time. But wait, you already know how many characters you have (you count them in counter, don't you?). So why not use counter to compute the index where the new character should be placed? (be careful not to do the same mistake and overwrite something else).
The function is wrong.
This statement
int lastElement = strlen(chunk) - 1;
can result in undefined behavior of the function because firstly the array chunk is not initially initialized
char chunk[7];
and secondly after this statement
memset(chunk, '\0', sizeof chunk);
the value of the variable lastElement will be equal to -1.
This if statement
if (chunk != NULL)
{
printf(chunk);
}
does not make sense because the address of the first character of the array chunk is always unequal to NULL.
It seems that what you mean is the following.
#include <stdio.h>
#include <ctype.h>
void stringSplit( const char s[] )
{
const size_t N = 6;
char chunk[N + 1];
size_t i = 0;
for ( ; *s; ++s )
{
if ( !isspace( ( unsigned char )*s ) )
{
chunk[i++] = *s;
if ( i == N )
{
chunk[i] = '\0';
i = 0;
puts( chunk );
}
}
}
if ( i != 0 )
{
chunk[i] = '\0';
puts( chunk );
}
}
int main(void)
{
char s[] = " You and I are beginners in C ";
stringSplit( s );
}
The program output is
Youand
Iarebe
ginner
sinC
You can modify the function such a way that the length of the chunk was specified as a function parameter.
For example
#include <stdio.h>
#include <ctype.h>
void stringSplit( const char s[], size_t n )
{
if ( n )
{
char chunk[n + 1];
size_t i = 0;
for ( ; *s; ++s )
{
if ( !isspace( ( unsigned char )*s ) )
{
chunk[i++] = *s;
if ( i == n )
{
chunk[i] = '\0';
i = 0;
puts( chunk );
}
}
}
if ( i != 0 )
{
chunk[i] = '\0';
puts( chunk );
}
}
}
int main(void)
{
char s[] = " You and I are beginners in C ";
for ( size_t i = 3; i < 10; i++ )
{
stringSplit( s, i );
puts( "" );
}
}
The program output will be
You
and
Iar
ebe
gin
ner
sin
C
Youa
ndIa
rebe
ginn
ersi
nC
Youan
dIare
begin
nersi
nC
Youand
Iarebe
ginner
sinC
YouandI
arebegi
nnersin
C
YouandIa
rebeginn
ersinC
YouandIar
ebeginner
sinC
I'm just learning C after learning Java and I'm having a tough time...
This program is supposed to be a simple command prompt program that takes in a command like "sum 1 2" and adds outputs "3". The program tokenizes the input by space into a 2d array. So the first element will have the command and the following integers will be for arithmetic. As soon as I type "sum 1 2" I get a segmentation fault error and the program crashes.
I set every row in my 2d array to "NULL" so that I could know when to stop iterating through the rows. I looked everywhere and I would like to know if this was an incorrect way of doing it, and if there's a more effective way.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define tLength 20
#define tRow 7
char input[tLength];
char tokens[tRow][tLength];
char p[tLength];
char y[tLength];
int counter = 0;
void getTokens(char inp[]) {
strcpy(y, inp);
strcpy(p, strtok(y," "));
strcpy(tokens[counter], p);
counter = 1;
while (p!=NULL){
strcpy(p,strtok(NULL, " "));
if (counter < tRow) {
strcpy(tokens[counter], p);
counter++;
}
else {
printf("Cannot process more lines");
counter = 0;
break;
}
}
counter = 0;
}
void commandLine() {
int count;
for (count=0;count<tRow;count++){
strcpy(tokens[count],"NULL");
}
printf(">");
fgets(input, tLength, stdin);
getTokens(input);
if (strcmp("quit", tokens[0]) == 0 || strcmp("Quit", tokens[0]) == 0) {
printf("Bye!");
}
else if (strcmp("sum", tokens[0]) == 0 || strcmp("Sum", tokens[0]) == 0) {
int sum = 0;
counter = 1;
while (strcmp("NULL",tokens[counter])!=0) {
sum += atoi(tokens[counter]);
counter++;
}
counter = 0;
printf("%d", sum);
}
else if (strcmp("prod", tokens[0]) == 0 || strcmp("Prod", tokens[0]) == 0) {
int temp = 0;
int prod = 1;
counter = 1;
if (atoi(tokens[1]) == 0) {
printf("%d", 0);
}
else {
while (strcmp("NULL",tokens[counter])!=0) {
prod *= atoi(tokens[counter]);
counter++;
}
}
printf("%d", prod);
}
else {
printf("Error, unknown command");
}
}
void main(void) {
commandLine();
}
Several tips:
global variables when unecessary, are bad
use capital letters for macros
better initialize variables, than left uninitialized
use descriptive variable names ( not, p, y etc )
empty string can't be compared to "NULL"
POSIX offers strcasecmp which is case insensitive version of strcmp
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXINPUTLEN 20
#define MAXTOKENS 7
void getTokens( char* input, char tokenized[][MAXINPUTLEN] )
{
int counter = 0;
char* token = strtok( input, " " );
while( token != NULL )
{
if( counter < MAXTOKENS )
{
strncpy( tokenized[counter], token, MAXINPUTLEN );
counter++;
}
else
{
printf( "Cannot process more lines" );
counter = 0;
break;
}
token = strtok( NULL, " " );
}
counter = 0;
}
void commandLine()
{
char input[MAXINPUTLEN] = {0};
printf( ">" );
fgets( input, MAXINPUTLEN, stdin );
char tokens[MAXTOKENS][MAXINPUTLEN] = {{0}};
getTokens( input, tokens );
if( strcasecmp( "quit", tokens[0] ) == 0 )
{
printf( "Bye!" );
}
else if( strcasecmp( "sum", tokens[0] ) == 0 )
{
int sum = 0;
for( int i = 1; tokens[i][0] != 0; ++i )
{
sum += atoi( tokens[i] );
}
printf( "%d", sum );
}
else if( strcasecmp( "prod", tokens[0] ) == 0 )
{
int prod = 1;
for( int i = 1; tokens[i][0] != 0; ++i )
{
prod *= atoi( tokens[i] );
}
printf( "%d", prod );
}
else
{
printf( "Error, unknown command" );
}
}
int main( void )
{
commandLine();
return 0;
}
Arrays in C work differently than in Java.
In C, arrays are primitive types. You cannot assign NULL to an array in C.
In Java, an array is an object reference; you need to create an array object and assign it to the array variable.
In fact, Java arrays are more like C pointers.
Your code makes excessive use of global variables and tries to call strcpy on a NULL pointer when you reach the last token.
You should use a pointer to capture the return value from strtok:
/* Returns the number of tokens captured. */
int getTokens(char inp[]) {
char *p;
int counter = 0;
strcpy(y, inp);
p = strtok(y," ");
while (p!=NULL){
if (counter < tRow) {
strcpy(tokens[counter], p);
counter++;
}
else {
printf("Cannot process more lines");
counter = 0;
break;
}
}
return counter;
}
Note: There may be more errors in the code. I never made it past getTokens.
I am writing a code to remove the repeated occurrence of a character in the string.
Description:- Remove the repeated characters from the string
Example:-
Sample Input = abcdeabd
Sample Output =abcde
I have written the code and it is working and when I tested by running sample test cases ,It is passing most of the test cases but is failing some e.g. when I Use the input string as "abcdabcdabcdabcd" It is giving me abcdd as the output instead of "abcd"
Here is my code
#include<stdio.h>
int main(void)
{
char a[60]="abcdeabd";
int n=0;
for(int l=0;a[l]!='\0';++l)
++n;
printf("%d\n",--n);
for(int i=0;i<=n;++i)
{
for(int j=i+1;j<=n;++j)
{
if(a[i]==a[j])
{
for(int k=j;k<=n;++k)
a[k]=a[k+1];
--n;
}
}
}
puts(a);
return 0;
}
Please tell me where I am going wrong with this code...?
The logic error is in the block
if(a[i]==a[j])
{
for(int k=j;k<=n;++k)
a[k]=a[k+1];
--n;
}
It doesn't work when you have the same character more than twice in succession. It doesn't work for `"addd" or "adddbc".
Change that to a while loop to fix the problem.
while (a[i] == a[j])
{
for(int k=j;k<=n;++k)
a[k]=a[k+1];
--n;
}
As for me I would write a corresponding function using pointers. For example
#include <stdio.h>
char * unique( char *s )
{
char *last = s, *current = s;
do
{
char *t = s;
while ( t != last && *t != *current ) ++t;
if ( t == last )
{
if ( last != current ) *last = *current;
++last;
}
} while ( *current++ );
return s;
}
int main(void)
{
char s[]="abcdeabd";
puts( s );
puts( unique( s ) );
return 0;
}
The output is
abcdeabd
abcde
As for your code then I would rewrite it the following way Take into account that you have to copy also the terminating zero.
#include <stdio.h>
char *unique( char *s )
{
int n = 0;
while ( s[n++] != '\0' );
printf( "%d\n", n );
for ( int i = 0; i < n; ++i )
{
for ( int j = i + 1; j < n; ++j )
{
if ( s[i] == s[j] )
{
--n;
for ( int k = j; k < n; ++k ) s[k] = s[k+1];
}
}
}
return s;
}
int main(void)
{
char s[]="abcdeabd";
puts( s );
puts( unique( s ) );
return 0;
}
#include<stdio.h>
int main(void)
{
char a[10]="abcdeabd";
for(int i=0;a[i]!='\0';++i)
printf("\n %c", a[i]);
for(i=0;a[i]!='\0';++i)
for(int j=i+1;a[j]!='\0';++j)
if(a[i]==a[j])
for(int k=j;a[k]!='\0';++k)
a[k]=a[k+1];
puts(a);
return 0;
}
#Patel: Your program is correct.
You missed only one single thing.
When You used printf(), you decrement the value of n.
So put a line to increment it after printf()
++i;