I have this code excerpt and don't understand some syntax in it.
What does string[index] = '!' mean?
What does string[index] == '~' mean?
And (string[index]++) probably means (the value of string[index] + 1)? The problem is that, in a larger context, that value should be a character. So, will it be treated as an ASCII code?
// Function to increment character and carry over if necessary
void incrementChar(char string[], int index)
{
if (string[index] == '\0')
{
string[index] = '!';
}
else if (string[index] == '~')
{
string[index] = '!';
incrementChar(string, index + 1);
}
else
{
string[index]++;
}
}
Related
I want to count how many this word and operator in the string but I try to use strchr and it doesn't work.
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main()
{
int x,count =0;
char buff[100]="1+2.3(7^8)sin cos + cos sin_e-2x+x2*2!/_x1 sine";
//gets(buff);
strupr(buff);
for (int i = 0; buff[i] != '\0'; i++)
{
if (buff[i] == '+' || buff[i] == '-' || buff[i] == '*' ||
buff[i] == '/' || buff[i] == '^'|| buff[i] == '(')
{
count++;
}
}
char *op2;
int check=0;
char cpysin[100],cpycos[100];
strcpy(cpysin,buff);
strcpy(cpycos,buff);
do
{
if(strchr(cpysin,'SIN')!=0)
{
count++;
strcpy(cpysin,strstr(cpysin,"SIN"));
cpysin[0] = ' ';
cpysin[1] = ' ';
cpysin[2] = ' ';
}
else
{
break;
}
}
while(check==0);
do
{
if(strchr(cpycos,'COS')!=0)
{
count++;
strcpy(cpycos,strstr(cpycos,"COS"));
cpycos[0] = ' ';
cpycos[1] = ' ';
cpycos[2] = ' ';
}
else
{
break;
}
}
while(check==0);
printf("FINAL \n%d",count);
}
I only work when I do it in the loop while trying to find how many sins are in there but it doesn't work when I put cos function on it. Please tell me how to fix this and what if I need to write more functions to find.
strchr(cpysin, 'SIN') is wrong.
Unfortunately the compiler may not give you a warning because 'SIN' can be interpreted as 4 byte integer. The second parameter is supposed to be an integer, but strchr really wants character, it chops it off to 'N'
Just remember that in C you work with single characters 'a' or strings "cos" (or you can come accross wide characters/strings)
Use strstr to find a string. For example, to find "cos":
char* ptr = buff;
char* find = strstr(ptr, "cos");
"1+2.3(7^8)sin cos + cos sin_e-2x+x2*2!/_x1 sine";
---------------^ <- find
find will point to "cos + cos sin_e-2x+x2*2!/_x1 sine"
You can increment ptr and look for the next occurrence of "cos".
Also note, you can declare char buff[] = "...", you don't have to assign the buffer size.
char buff[] = "1+2.3(7^8)sin cos + cos sin_e-2x+x2*2!/_x1 sine";
int count = 0;
const char* ptr = buff;
const char* text = "cos";
//must terminate when ptr reaches '\0' which is at the end of buff
//there is serious problem if we read past it
while(*ptr != '\0')
{
char* find = strstr(ptr, text);
if (find != NULL)
{
printf("update [%s]\n", find);
count++;
ptr = find + strlen(text);
//next search starts after
}
else
{
ptr++;
//next character start at next character
}
}
printf("%s count: %d\n", text, count);
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 3 years ago.
Improve this question
I have a simple program to find the vowels in a string. The for loop is supposed to iterate through the string and see if the char matches any of the vowels using and if else block but the output is just 100 As.
I tried making them all just ifs but that gave all Us.
#include <stdio.h>
int main()
{
const int SIZE = 100;
char str[SIZE] = {"the brown fox\0"};
char vowels[SIZE];
for (int i = 0; i <= SIZE; i++) {
if (str[i] == '97' || '65') {
vowels[i] = 'a';
}
else if (str[i] == '101' || '69' ) {
vowels[i] = 'e';
}
else if (str[i] == '105' || '73') {
vowels[i] = 'i';
}
else if (str[i] == '111' || '81') {
vowels[i] = 'o';
}
else if (str[i] == '117' || '85') {
vowels[i] = 'u';
}
printf("%c", vowels[i]);
}
return 0;
}
EDIT: Fixed the assignment if e.g. (str[i] == '97' || str[i] == '65') now it's printing strange symbols
EDIT 2: New code
#include <stdio.h>
int main()
{
const int SIZE = 100;
char str[SIZE] = {"the brown fox\0"};
char vowels[SIZE];
for (int i = 0; i <= SIZE; i++) {
if (str[i] == 'a' || str[i] == 'A') {
vowels[i] = 'a';
}
else if (str[i] == 'e' || str[i] =='E' ) {
vowels[i] = 'e';
}
else if (str[i] == 'i' || str[i] == 'I') {
vowels[i] = 'i';
}
else if (str[i] == 'O' || str[i] == 'o') {
vowels[i] = 'o';
}
else if (str[i] == 'u' || str[i] == 'U') {
vowels[i] = 'u';
}
printf("%c", vowels[i]);
}
return 0;
}
EDIT 3: Even after initialing vowels to '' at the start of the loop as suggested the strange symbols are gone but it's still not functioning properly.
You are comparing your char str[i] with '97'
6.4.4.4
An integer character constant has type int. The value of an integer character constant containing a single character that maps to a single-byte execution character is the numerical value of the representation of the mapped character interpreted as an integer. The value of an integer character constant containing more than one character (e.g., 'ab'), or containing a character or escape sequence that does not map to a single-byte execution character, is implementation-deļ¬ned.
If you want to compare a char you can use the ascii value for example 97 or directly the char with 'c'.
For more maintenability and readability I prefer using the char directly.
There is other problems in your code:
First, in your for loop: for (int i = 0; i <= SIZE; i++) {
You are going too far in your array because of your <= as arrays id starts with 0, if you type str[100], in reality you are using the 101st char.
Another problem is your if statements: if (str[i] == '97' || '65') {
Here your if statement is equivalent to if (str[i] == '97' || '65' != 0) {
Consider retyping str[i] == : if (str[i] == '97' || str[i] == '65') {
Plus don't forget the first problem I mentionned about your '97'
You have a very large number of small problems summarized below:
#define SIZE 100 /* if you need a constant, #define one (or more) */
...
char vowels[SIZE] = ""; /* initialize all zero, {0) is valid also */
An integer constant is created by #define or by use of an enum. A const qualified int is not a constant integer. (that said VLAs are legal in C99, but optional in C11)
int idx = 0; /* separate index for filling vowels array */
Keep a separate index for filling the vowels array.
/* don't use magic-numbers in your code */
if (str[i] == 'a' || str[i] == 'A') {
Don't use magic-numbers, instead, use literal character constants were needed in your code to produce much more readable code.
Your program takes arguments, use them to pass the string to parse (or read from stdin), e.g.
int main (int argc, char **argv) {
const char *str = (argc > 1) ? argv[1] : "the brown fox";
...
The test ? if_true : if_false operator is called the ternary operator. It allows a simple in-line conditional to select one of two values based on the test condition (e.g. (argc > 1))
If you plan on using vowels as a string, don't forget to nul-terminate vowels after the loop, e.g.
vowels[idx] = 0; /* nul-terminate vowels */
Correcting all the errors and adding the arguments to main() you could do something similar to:
#include <stdio.h>
#define SIZE 100 /* if you need a constant, #define one (or more) */
int main (int argc, char **argv) {
const char *str = (argc > 1) ? argv[1] : "the brown fox";
char vowels[SIZE] = ""; /* initialize all zero, {0) is valid also */
size_t idx = 0; /* separate index for filling vowels array */
for (int i = 0; idx < SIZE - 1 && str[i]; i++) {
/* don't use magic-numbers in your code */
if (str[i] == 'a' || str[i] == 'A') {
vowels[idx++] = 'a'; /* assign 'a', increment index */
}
else if (str[i] == 'e' || str[i] == 'E' ) {
vowels[idx++] = 'e';
}
else if (str[i] == 'i' || str[i] == 'I') {
vowels[idx++] = 'i';
}
else if (str[i] == 'o' || str[i] == 'O') {
vowels[idx++] = 'o';
}
else if (str[i] == 'u' || str[i] == 'U') {
vowels[idx++] = 'u';
}
}
vowels[idx] = 0; /* nul-terminate vowels */
printf (" %zu vowels: ", idx); /* print number of vowels */
for (int i = 0; vowels[i]; i++) /* output each vowel, comma-separated */
printf (i > 0 ? ", %c" : "%c", vowels[i]);
putchar ('\n'); /* tidy up with newline */
return 0;
}
Example Use/Output
bin\vowels.exe "a quick brown fox jumps over the lazy dog"
11 vowels: a, u, i, o, o, u, o, e, e, a, o
Depending on your compiler str[i] == '117' (and the rest) may give you an error as signle quotes are only to be used when you want to implement the ascii equivalent of a single character like 'a' or so. Therefore str[i] == '117' is checking if str[i] is equal to the ascii equivalent of "117".
Other than that " || " is a logical "or" operator. When you write down str[i] == '111' || '81' you simply mean "find ascii codes of 111 and 81(which dont exist) , use them in "or" operation, check if the result equals str[i]".
last but not least i found a nice function online which might help making your code more compact
int isvowel(int ch)
{
int c = toupper(ch);
return (c == 'A' || c == 'E' || c == 'I' || c == 'O' || c == 'U');
}
to explain it shortly, if the char equivalent of given int ch is lowercase, the function changes it to uppercase and checks if it is an uppercase vowel, if the given integer already equals an uppercase vowel int c = toupper(ch); doesnt change anything.
Implementation can be done as:
for(int i=0; i<SIZE; i++) //scan all emelents of str[SIZE]
{
if(isvowel(str[i])) //print if vowel
printf ("%c", str[i]);
}
My code runs well to my surprise!!
The only problem is that whenever I use a bracketed infix input it comes out a 'J' at the end of postfix expression !! Any suggestions??
Here the algorithm is the basic one all expressions are getting converted and all is right but the tailing 'J' is i just cann't understand !! Suggestions??
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<ctype.h>
#define MAX 50
char stack[MAX];
int top = -1;
void push(char element)
{
stack[++top] = element;
}
char pop()
{
return(stack[top--]);
}
char tope()
{
return(stack[top]);
}
int prec(char c)
{
switch(c){
case '+':
case '-' : return 1;
break;
case '*' :
case '/' : return 2;
break;
default:
return 0;
break;
}
}
int main()
{
char post[MAX],in[MAX],ch,element;
printf("Infix expression : ");
scanf("%s",in);
int i=0,k=0;
in[strlen(in)] = ')';
push('(');
while((ch = in[i++]) != '\0')
{
if(isalnum(ch))
post[k++] = ch;
if(ch == '(')
push(ch);
if(ch == ')')
{
while(tope() != '(')
{
post[k++] = pop();
}
pop();
}
if(ch == '+' || ch =='-' || ch == '*' || ch == '/')
{
while(prec(ch) <= prec(tope()))
{
post[k++] = pop();
}
push(ch);
}
}
post[k] = '\0';
printf("%s",post);
return 0;
}
in[strlen(in)] = ')';
overwrites the nul-terminating character, which explains strange chars when printing (printing stops only when meeting another nul char by luck: undefined behaviour which may even lead to a crash if no nul char is found in the in 50-byte buffer)
You have to shift it, for instance like this:
int l = strlen(in);
in[l] = ')';
in[l+1] = '\0';
Note: you have to store the length of your string in l instead of calling strlen(in) twice not only because of the performance loss but, because putting the parenthesis means that strlen doesn't work properly until you null-terminate.
(also you probably want to protect your scanf like this: scanf("%48s",in); so you're sure to have enough room for the extra parenthesis for your 50-size buffer, even compatible with your macro definition, see scanf: template with macro (#define constant) inside)
I am in the process of writing an infix to postfix function. After it loops through a couple of times(8 or 9th loop), my postfix array won't accept any more characters(it's set for 100).
void convertToPost(char infix[], char postfix[])
{
StackNode *pMem=NULL;
int i=-1,j=0, priority=0,priorityStack=0,operandCounter=0;
push(&pMem,'(');
infix[strlen(infix)]=')';
printf("%s\n",infix);
for(j=0;j<strlen(infix);j++)
{
putchar('\n');
printf("infix[%d]: %s\n",j,infix);
printf("postfix[%d]: %s\n",j,postfix);
putchar('\n');
if(infix[j] <= 57 && infix[j] >= 48)
{
i++;
postfix[i]=infix[j]; // not assigning value 8 to postfix
i++;
postfix[i] = ' ';
}
else if(infix[j] == '(')
{
push(&pMem,infix[j]);
//pop(&pMem);
}
else if(infix[j] == ')')
{
while(pMem->pNext != NULL)
{
if(pMem->pString == '(')
{
pop(&pMem);
}
else
{
postfix[i]= ' ';
i++;
postfix[i] = pMem->pString;
i++;
pop(&pMem);
}// figure out how to take char from top of stack and put in postfix something pop()
//push(&pMem,'(');
}
push(&pMem,'(');
//pop(&pMem);
}
else if(infix[j] == '+' || infix[j] == '-' || infix[j] == '^' || infix[j] == '*' || infix[j] == '/' || infix[j] == '%')
{
//i--;
if(operandCounter==0)
{
push(&pMem,infix[j]);
operandCounter++;
}
else
{
priority=Precedence(infix[j]);
priorityStack=Precedence(pMem->pString);//pString is empty
if(priority >= priorityStack)
{
if(pMem->pString != '(')
{
i++;
postfix[i]=pMem->pString;
i++;
postfix[i]=' ';
pop(&pMem);
push(&pMem,infix[j]);
}
else
{
push(&pMem,infix[j]);
}
}
}
}
}
}
This is the sample equation that I am using: 9*(5-4)+2/6
Its output should be: (9 5 4 - * 2 6 / +)
I put a comment where the problem occurs first. It continues throughout after it reaches that point. For example when I run the code it returns: 9 5 4 - *
But gives no error codes or anything.
If you would like some of the other functions (i.e priority, push, pop) feel free to ask.
inside the for loop(), strlen(infix) value is undefined. Because you are replacing the terminating NULL character in the string.infix[strlen(infix)]=')'; Which causes strlen() to return undefined value.
so change
infix[strlen(infix)]=')';
to
int len = strlen(infix);
infix[len]=')';
infix[len+1] = '\0';
Also make sure you have sufficient memory allocated for the array so the len+1 index in the array will not be out of bounds access.
I am trying to make a program that will take as input a string and replace all the vowels with the * symbol. So, for "hello world", star_vowels should return "h*ll* w*rld".
What I have for code so far is:
int star_vowels(char s[]){
int j;
j = 0;
while (s[j] != '0'){
j++;
if (s[j] = 'a' || s[j] == 'e' || s[j] == 'i' || s[j] == 'o' || s[j] == 'u'){
putchar('*');
} else {
putchar(j);
}
return 0;
}
}
This code has a number of things wrong with it.
1) while (s[j] != '0')
I'm fairly sure you want to be checking for the NUL character, not the character constant zero. Change '0' to '\0'
2) j++
you are incrementing j before you even look at the 0th index of your array. If you had a vowel at s[0], this would be missed. Move j++ to the very bottom of the while loop, just before the ending brace.
3) s[j] = 'a'
You are using the assignment operator = here when you should be using the equality operator == instead. Using the assignment operator is legal C code and thus will compile. Unfortunately it will return true and you'll end up replacing all of your characters with asterisks
4) putchar(j);
You are attempting to output 'j' (your iterator) when you really want to be outputting s[j] (your character).
5) return 0
just like in #2, your return statement is in the wrong place. You have it within the while loop when it should be outside of it. The way you have it written, the while loop will only execute the first iteration before your function goes out of scope.
int star_vowels(char s[]) {
int j = 0;
while (s[j] != '\0'){
if (s[j] == 'a' || s[j] == 'e' || s[j] == 'i' || s[j] == 'o' || s[j] == 'u') {
putchar('*');
} else {
putchar(s[j]);
}
j++;
}
return 0;
}
I think your question is going to be 'everything is *' and that's because of this part of your giant if:
if (s[j] = 'a'
That will always be true. You need the ==
Also you put j++ too early - you'd skip characters because you immediately increment upon entering the loop.
By incrementing the j at the beginning you will lose the 0 index (the first character).
Since you want to return new data to the outside world (outside the function scope), you either allocate memory for the new data outside the function, and pass in a pointer of that data to this function, or you just allocate dynamic memory inside this function - remember to delete it.
One implementation would be:
char *star_vowels(char s[]){
// let's allocate memory for the new string.
// its size should be strlen(s) + 1 (the ending char).
char *final = malloc(strlen(s) + 1);
int j = 0;
while (s[j] != 0){
if (s[j] == 'a' || s[j] == 'e' || s[j] == 'i' || s[j] == 'o' || s[j] == 'u'){
final[j] = '*';
} else {
final[j] = s[j];
}
j++;
}
final[j] = 0; // end the string
return final;
}
Working example: http://codepad.org/dd2w5cuy