Warning: comparison between pointer and integer - c

I started learning C language and my task is to write a script that will check the text in the txt file for the presence of the word ananas, but you can’t use strlen(), strcpy(), strcmp(). I wrote code that doesn’t work, but the output is simple 0. I understand why it outputs something, but I don’t understand how to do it so it worked fine.
And when I compile the code, I get this error
warning: comparison between pointer and integer
if(c[i] == s || ss){
This is my code
#include <stdio.h>
#include <stdlib.h>
int main() {
FILE *f;
char c[1000];
char a[] = {'a'};
char aa[] = {'A'};
char n[] = {'n'};
char nn[] = {'N'};
char s[] = {'s'};
char ss[] = {'S'};
int g = 0;
int col = 0;
f = fopen("bananas1.txt", "r");
fgets(c, 1000, f);
for(int i = 0; i < 1000; i++){
for(int q = 0; q < 1;){
if(c[i] == a || aa){
q++;
}
if(c[i] == n || nn){
q++;
}
if(c[i] == s || ss){
q++;
}
if(q == 1){
g++;
q = 0;
}
if(q == 0){
g = 0;
}
}
if(g == 6){
col++;
}
}
printf("%d", col);
fclose(f);
return 0;
}
Here is the text that I need to check in the bananas1.txt file
Bananas are edible fruits, botanically berries. In some countries, bAnAnAs used for cooking are called plantains, distinguishing them from dessert bananaS. The fruits grow in clusters hanging from the top of the plant. Almost all modern edible seedless BANANAS come from two wild species of Musa acuminata and Musa balbisiana. The scientific names of most cultivated bananas are Musa acuminata, Musa balbisiana, and Musa X paradisiaca, depending on their genomic constitution.
As you can see, there is the word bananas, and it contains the word bananas; I need to count the number of ananas words in this text.

I assume that this
if(c[i] == a || aa){
is meaning to say
"if c[i] is either 'a' or 'aa' then ..."
Sadly, C doesn't work like that. The attempt to compare a char (c[i) with an array of chars (a, even though it's only one character) is why you are getting the error.
You need
if(c[i] == 'a')....
or
char a = 'a';
if(c[i] == a)...
there is no way to look to see if one char is equal to 2 chars (!). If you need to look for 'aa' then you have to look for an a then look at the next char too
Also you cannot do shortcut 'ors'
if(c[i] == 'a' || 'b')
does not say "if c[i] == a or c[i] == b".

Related

I made a program, but can't seem to find the error, anyone has got a clue?

#include <stdio.h>
int main() { //main function
char string1[400] = "Pinot noir is a red wine grape variety of the species Vitis vinifera. The name may also refer to wines created predominantly from Pinot noir grapes. The name is derived from the French words for pine and black. The word pine alludes to the grape variety having tightly clustered, pine cone-shaped bunches of fruit.[1].";
char string2[400] = "Metallica is an American heavy metal band. The band was formed in 1981 in Los Angeles by vocalist/guitarist James Hetfield and drummer Lars Ulrich, and has been based in San Francisco for most of its career.[1][2] The band's fast tempos, instrumentals and aggressive musicianship made them one of the founding big four bands of thrash metal, alongside Megadeth, Anthrax and Slayer.";
char str[15]; //string declaration
printf("Enter the word to be searched : ");
scanf_s("%s", str); //taking word from user
int i, k = 0, length = 0, count1 = 0, count2 = 0; //declaring required variables
for (i = 0; str[i] != '\0'; i++) { //calculate length of given word
length++;
}
for (i = 0; string1[i] != '\0'; i++) { //loop through string1
if (str[k] == string1[i]) { //if character of word equals to character of string1
i++;
if (k == length && string1[i - length] == ' ' && string1[i + 1] == ' ') { //checking spaces front and back of the word in string1
count1++; //incrementing count
k = 0;
}
} else {
k = 0;
}
}
for (i = 0; string2[i] != '\0'; i++) { //same logic as we found word in string1
if (str[k] == string2[i]) {
k++;
if (k == length && string1[i - length] == ' ' && string1[i + 1] == ' ') {
count2++;
k = 0;
}
} else {
k = 0;
}
}
printf("'%s' is found %d times in the String1.\n", str, count1);
//printing count in String1
printf("'%s' is found %d times in the String2.", str, count2);
//printing count in String2
}
The compiler complains because you are using scanf_s incorrectly.
Microsoft insists on using scanf_s instead of scanf, but just changing the function name is insufficient: you should pass the destination array size in addition to the destination array pointer.
The problem is Microsoft's version of scanf_s API differs from the C Standard version and this function is not supported on many platforms, making it non portable.
You should use the standard function scanf and pass the maximum number of characters to store into str this way:
if (scanf("%14s", str) != 1) {
fprintf(stderr, "invalid or missing input\n");
return 1;
}
To prevent the compiler error, you can add this definition before the #include <stdio.h>:
#define _CRT_SECURE_NO_WARNINGS 1
You scanning code is incorrect too:
you will miss some matches such as aab in aaab
the test for separators is incorrect and will fail or cause undefined behavior in all cases.
you should use a function to avoid duplicating the code.
Here is a modified version:
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
size_t count_matches(const char *s, const char *str) {
size_t i, k, count = 0;
for (i = 0; s[i] != '\0'; i++) {
if (i == 0 || s[i - 1] != ' ') {
// if at the beginning of a word, try matching
for (k = 0;; k++) {
if (str[k] == '\0') {
// check for end of word in s
if (s[i + k] == '\0' || s[i + k] == ' ')
count++;
break;
}
if (s[i + k] != str[k])
break;
}
}
}
return count;
}
int main() { //main function
char string1[] = "Pinot noir is a red wine grape variety of the species Vitis vinifera. The name may also refer to wines created predominantly from Pinot noir grapes. The name is derived from the French words for pine and black. The word pine alludes to the grape variety having tightly clustered, pine cone-shaped bunches of fruit.[1].";
char string2[] = "Metallica is an American heavy metal band. The band was formed in 1981 in Los Angeles by vocalist/guitarist James Hetfield and drummer Lars Ulrich, and has been based in San Francisco for most of its career.[1][2] The band's fast tempos, instrumentals and aggressive musicianship made them one of the founding big four bands of thrash metal, alongside Megadeth, Anthrax and Slayer.";
char str[15];
printf("Enter the word to be searched : ");
if (scanf("%14s", str) != 1) {
fprintf(stderr, "invalid or missing input\n");
return 1;
}
int count1 = count_matches(string1, str);
int count2 = count_matches(string2, str);
printf("'%s' is found %d times in the String1.\n", str, count1);
printf("'%s' is found %d times in the String2.\n", str, count2);
return 0;
}

Issue with String position appending C program

I am trying to write program for piglatin. I was not getting the output what I am expecting.
take the first letter of a “word” and appending that letter to the end of the word with “ay” added to the end as well.
Input : Darrin, what are you doing with 500 and 100?
Output: arrin, hatway reaay ouyay oingday ithway 500 ndaay 100?
Expected Output: arrinday,hatway reay ouyay oingday ithway 500 nday 100?
What's wrong with output : First word not appended with ay
Since I am appending 'ay', I need eliminate the extra 'a' if the word starts with a or end's with 'a'. I just need add ay at the end instead of first letter + ay. For example: Input is Alex and allen are 500 Output should be lexay nday llenay
Also if the starting letter is not alphabet then we should return the same word.
Please help me to solve this
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
static char inputBuffer[100];
static char outputBuffer[100];
void translate (void)
{
char bufferValue;
char firstLetter;
int j = 0, k = 0, m = 0;
printf("\n");
while (j < (sizeof(inputBuffer) - 1))
{
bufferValue = inputBuffer[j];
if (((bufferValue >= 'A') && (bufferValue <= 'Z')) || ((bufferValue >= 'a') && (bufferValue <= 'z')))
{
if (j == 0)
{
firstLetter = bufferValue;
}
else if (inputBuffer[j-1] == ' ')
{
firstLetter = bufferValue;
}
else
{
printf("%c", bufferValue);
outputBuffer[m] = bufferValue; m++;
}
}
else if ((bufferValue == ' ') && !(
((inputBuffer[j-1] < 'A') ||
((inputBuffer[j-1] > 'Z') && (inputBuffer[j-1] < 'a')) ||
(inputBuffer[j-1] > 'z'))))
{
printf("%cay%c", firstLetter, bufferValue);
outputBuffer[m] = firstLetter; m++;
outputBuffer[m] = 'a'; m++;
outputBuffer[m] = 'y'; m++;
outputBuffer[m] = bufferValue; m++;
firstLetter = ' ';
}
else
{
printf("%c", bufferValue);
outputBuffer[m] = bufferValue; m++;
}
j++;
}
printf("\n final output: %s",outputBuffer);
return;
}
int main(void)
{
printf("enter the string\t");
fflush(stdin);
gets(inputBuffer);
printf ("\nInput buffer contents: %s", inputBuffer);
translate();
return 0;
}
First word not appended with ay
The problem is just not that only the first word is not being appended by first letter and ay, but whenever you have some non alphabet character at the end of a word (digits/special characters, except space), ay will not be appended to that word.
For example, try this input:
Darrin, what, are you doing with 500 and 100?
You'll get the output:
arrin, hat, reaay ouyay oingday ithway 500 ndaay 100?
So mainly, the problem is in the last else you have:
else
{
printf("%c", bufferValue);
outputBuffer[m] = bufferValue; m++;
}
See, when , comes immediately after a word, the control comes to this else and it just adds the , as it is, it does not append the firstLetter and ay.
But you can't always append firstLetter and ay in this else, you'll have to come up with some kind of condition, so you could separate the 500 and Darrin,, cause 500 will also go through this else statement.
Maybe, you could try checking if firstLetter is an alphabet or not, if it is, then append the firstLetter and ay, otherwise not.
else
{
if ((firstLetter >= 'a' && firstLetter <= 'z') || (firstLetter >= 'A' && firstLetter <= 'Z'))
printf("%cay", firstLetter);
outputBuffer[m] = firstLetter; m++;
outputBuffer[m] = 'a'; m++;
outputBuffer[m] = 'y'; m++;
firstLetter = ' ';
}
printf("%c", bufferValue);
outputBuffer[m] = bufferValue; m++;
}
But this will still not process the words like 0abcdef,, which do have alphabets in it, but start with some non-alphabet character, so that's your call, if you want to put them to the numbers category (like 500), to leave them as they are, or to process them.
Here is the working example.
P.S. I've made some other changes too (which don't affect your output), but the major change was what I explained (which does).
EDIT:
From the comments below:
If the word starts with Vowel(a,e,i,o,u) then just add y else first letter + ay
You can write a function in your program called isVowel to check if some character is vowel or not:
int isVowel(char c)
{
c = tolower(c);
if (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u')
return 1;
return 0;
}
Now, you're adding ay at two places in your program:
In the else if and the last else:
outputBuffer[m] = firstLetter; m++;
outputBuffer[m] = 'a'; m++;
outputBuffer[m] = 'y'; m++;
firstLetter = ' ';
So, you can add an if at the statements outputBuffer[m] = 'a'; m++; to only add this a if the firstLetter is not a vowel:
outputBuffer[m] = firstLetter; m++;
if (!isVowel(firstLetter))
{
outputBuffer[m] = 'a';
m++;
}
outputBuffer[m] = 'y'; m++;
firstLetter = ' ';
change this at both places i.e. in the else if and else, and you'll be done.
I've updated the code on ideone
The real problem is that you didn't see the forest through the trees which made the implementation awful to read. To add insult to injury, you decided to break the basic rules of code locality (not using globals unless necessary) and DRY (functions to tell if a charater is a letter exist in the standard library of any language I can think of, don't reimplement it), which made it pretty much irrecoverable as far as maintenance is concerned.
Now, let's read the task description again:
take the first letter of a “word” and appending that letter to the end of the word with “ay” added to the end as well.
Notice what already stands out because of quoting: word.
So, I'd divide the implementation into two distinct tasks:
Iterate through a sentence word by word.
Once you can reliably identify words, do the piglatin thing.
The end result of might look like this:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
void piglatinize(const char* in)
{
static const char* SEP = " .,?"; // word separators
// Iterate input by words
const char *sep = NULL, *word = NULL, *end = in;
while (sep = end, // separators from previous word end
word = &end[strspn(end, SEP)], // start of word
end = &word[strcspn(word, SEP)], // end of word
*sep) // iterate until we hit terminating zero character
{
int wordlen = (int)(end - word);
int seplen = (int)(word - sep);
if (wordlen > 0 && isalpha(word[0])) // word starts with a letter, pig it!
{
char firstletter = tolower(word[0]);
const char* suffix = (firstletter == 'a') ? "y" : "ay";
printf("%.*s%.*s%c%s",
seplen, sep, // separators from previous word
wordlen - 1, &word[1], // word without first letter
firstletter, suffix);
}
else // not a real word, just print unchanged
{
printf("%.*s%.*s", seplen, sep, wordlen, word);
}
}
}
int main()
{
piglatinize("Darrin, what are you doing with 500 and 100?");
}
I admit the while loop continuation condition is a handful. If you have trouble understanding this example you might want to read on strspn (and its opposite strcspn) and the comma operator.

reverse sentence while maintaining the location of space in C language

i got headache trying to solve this assignment of mine..here is the question:
Reverse the order of words
Write a function to reverse the order of words
Given a sentence of words in a character array, write a C function to reverse the order of words.
char* reverse_word_order (char* str);
The function gets a character array as its sole argument, reverses the order of words in it, and puts back the result into it. It returns the pointer to the argument on termination for convenience sake.
See the following example.
char str[] = `" this is very beautiful "`;
printf ("[%s]\n", reverse_word_order(str)); /* print `[beautiful very is this ]` */
Beware that the location of space characters has not moved; the result of the example above is [beautiful very is this ], not [ beautiful very is this].
The following constraints apply:
No external function calls. (strlen, strcpy, etc). No explicit memory
allocation on the heap (malloc, realloc, dynamic arrays, etc) If you
need these functions, write your own.
i wrote this code:
#include <stdio.h>
int length (char* str){
int L=0;
while(*str++){
L++;
}
return L;
}
int Last(char* zi) {
int i;
for(i=length (zi); i>0;i--){
if (zi[i]!='\0'){
return i;
}
}
}
void reverse_substring(char* zi, int start, int end){
char Temporary;
int i,z;
for(i=start, z=end; i<z; i++,z--){
Temporary = zi[i];
zi[i]=zi[z];
zi[z]=Temporary;
}
}
char* reverse(char* zi){
char *str = zi;
int len = length (zi);
int i=0;
int count=0;
reverse_substring(str,0,Last(str));
while(i<=len){
if(str[i] ==' ' || i==len){
reverse_substring(str,i-count,i-1);
count=0;
}
if(str[i]!=' '){
count++;
}
i++;
}
return str;
}
int main(int argc, char **argv){
char str[] = " this is very beautiful ";
printf("Length of string: %d\n",length(str));
printf("[%s]\n", reverse(str));
}
but the output from the code above is : [ beautiful very is this] which does not confirm the requirement of the question.
the output should be :[beautiful very is this ]
any ideas?
thanks.
Ok: so I added two functions one that strips all the unnecessary spaces and counts their amount and the other that puts them together. I will just copy the main and the functions here.
void strip_spaces(char *str, int *spaces)
{
int len = length(str);
int i, j, l, flag;
for (i = 0; i < 100; i++)
spaces[i] = 0;
i = 0; j = 0; l = 0;
while(str[i] != '\0'){
flag = 0;
while(str[i] == ' '){
i++;
flag = 1;
spaces[l]++;
}
if (flag == 1){
l++;
str[j++] = ' ';
}
else{
str[j++] = str[i++];
}
}
str[j] = '\0';
}
void add_spaces(char *str, int *spaces)
{
int i = 0;
int flag;
int l = 0;
char stra[1000];
while(str[i] != '\0'){
stra[i] = str[i];
i++;
}
stra[i] = str[i] = '\0';
printf("%s*\n%s*\n", stra, str);
i = 0;
int j = 0;
while(stra[i] != '\0'){
flag = 0;
if(stra[i] == ' ')
while(spaces[j] > 0 ){
flag = 1;
spaces[j]--;
str[l] = ' ';
l++;
}
if (flag == 1){
j++;
i++;
}
else{
str[l++] = stra[i++];
}
}
str[l] = '\0';
}
int main(int argc, char **argv)
{
char str[] = " this is very beautiful ";
int spaces[100];
strip_spaces(str, spaces);
reverse(str);
add_spaces(str, spaces);
printf("Length of string: %d\n",length(str));
printf("%s\n", str);
return 0;
}
For simplicity, lets treat the string " this is very beautiful " as "X t~s A is B v~y C b~l Y", and the result you want is "X b~l A v~y B is C t~s Y". So the first step is the truely wonderful:
"X t~s A is B v~y C b~l Y" -- reverse the words...
"X s~t A si B y~v C l~b Y" -- reverse all but the leading and trailing...
"X b~l C v~y B is A t~s Y" -- shazam :-)
now the problem is that A, B and C are out of order. So let's try another reverse, excluding the stuff which is now in the right place at either end:
"X b~l A si B y~v C t~s Y"
which restores the order of A, B and C, but the words are in a mess. Since we only have a hammer, let's hit the thing again, again excluding stuff which is in the right place:
"X b~l A v~y B is C t~s Y"
By George ! I think we have it :-)
Obviously this can be extended to any number of words, by repeatedly moving in from the ends, reversing the stuff which is not yet in the required order, until there are no words left.
In this case we have an odd number of white-space sections. The solution may be slightly different with an even number of same... but I guess I should leave some of the exercise to you.
If the white-space sections are just spaces, the the order of those does not matter. But if they were a mixture of spaces and tabs (say), then you'd need to check that those ended up in the right order as well. (The analysis needs to be repeated but using, say, Aa, Bb, etc. and throwing in some extra reverses as required.)
I find that it can help to (a) try to cut away the clutter, and (b) sit down with a pencil an paper and doodle out the steps in the process -- on a small subset, or a simplified version, of the problem. Doing this can reveal the pattern(s) and allow me to visualise the process, which can then be checked against a more general version of the problem, and then translated into code.

Can you help me with multiple errors in C?

I'm pretty new to C and I'm having difficulty with a few different concepts, including pointers, arrays, and reading files. Here is my program I've started, I'm sure their are a few errors, could you show me what I'm doing wrong? The program is supposed to read the letters from congress.txt and store them as capital letters without spaces, I also tried to make a little test which will print the letters for me so I can see if the characters in the array store are correct. I've heard that I shouldn't test against != EOF here before but my teacher has used that and I don't want to simply copy something I don't understand.
This is what is in congress.txt:
Congress shall make no law respecting an establishment of religion, or prohibiting the free exercise thereof; or abridging the freedom of speech, or of the press; or the right of the people peaceably to assemble, and to petition the government for a redress of grievances.
#include<stdio.h>
int processFile(int *store);
int cipher(int *store, int *code);
int main(void){
int store[300], code[300], i;
processFile(store);
for (i = 0; store[i] != 0; ++i){ //does a print test of store so I can see if the txt was stored properly
printf("%c", store[i]);
}
getchar();
return;
}
int processFile(int *store){
int i, a = 0;
FILE *f = fopen("congress.txt", "r");
for (i = 0; a != EOF;){
fscanf(f, "%c", &a); //store character in a
if (a <= 'Z' && a >= 'A'){ //store capital letters
store[i] = a;
i++;
}
if (a <= 'z' && a >= 'a'){ //store lower case letters as capital
store[i] = a - 32;
i++;
}
}
}
This line:
fscanf(f, "%c", a);
should be:
fscanf(f, "%c", &a);
This loop doesn't make any sense.
for (i = 0; b != NULL; i++)
printf("%s", store[i]);
b = store[i + 1];
}
store[i] is an int, so you can't print it with "%s". I think you meant printf("%c", store[i]); which means to print the characters whose character code is that int (which is OK, because you read this earlier with scanf).
b != NULL should be b != 0, but this tests an uninitialized value of b on the first time around the loop. Try this instead:
for ( i = 0; store[i] != 0; ++i )
printf("%c", store[i]);
In the other piece of code, 65, 90, 97, 122 are more clearly expressed as 'A', 'Z', 'a', 'z' respectively.
You may want to consider using the isupper, islower functions from <ctype.h>. a - 32 should be replaced by toupper(a);.
I would change your body of processFile to:
int i, a = 0;
FILE *f = fopen("congress.txt", "r");
if(f)
{
for( i=0; i<300 && ((a=fgetc(f)) != EOF); i++)
{
if ( isupper(a) ){ //store capital letters
store[i] = a;
}
else if ( islower(a) ){ //store lower case letters as capital
store[i] = toupper(a);
}
}
fclose(f);
}
if (i==300) i--;
store[i] = 0; // always put a zero after the last element
// since your loop in main depends on it to exit.
This takes care of EOF problems, and also fixes potential overflows of the store array. (You might want to pass store's max size to the routine instead of hardcoding 300...)

Performing arithmetic on Characters in C

I am trying to write a program that adds, subtracts, multiplies, and divides a string of characters. Where I'm at now with the program is figuring out how to split the input string into two strings, and then perform the appropriate +-/*.
The input should look like this abc+aaa
and the output for that should be abc + aaa = bcd
How do I convert character strings into integer strings?
#include <stdio.h>
#include <math.h>
#include <string.h>
int main() {
printf("This is a pseudo arithmetic program");
char input[10];
input[10] = '\0';
char first [9];
first[9] = '\0';
char last [9];
last[9] = '\0';
int i = 0;
int b;
int e;
while (input[0] != '0') {
if (input[0] == 0){
return -1;
}
printf("\nEnter a math problem in SOS format using only lowercase letters up to 9 characters");
printf("\nEx: abc+abc... type '0' to quit \n");
scanf("%s", input);
int x = 0;
x = strlen(input);
if (strchr(input, '+')){
for (i = 0; i <= x; i++) {
if (i == '+')
strncpy(first, &input[0], i-1);
i = 0;
}
for (i = x; i >= input[0]; i--) {
if (i == '+')
strncpy(last, &input[i], x);
i = 0;
}
printf("%s", first);
printf(" + ");
printf("%s", last);
printf(" = %d", first + last);
}
There seems to be multiple problems with your code:
There is a array out of bounds happening for almost all the arrays:
char input[10];
input[10] = '\0';
In this if you want to initialize the last character with '\0' then it should be
input [9] = '\0'
Arrays indexes always start from 0.
It is not clear what is the use of below lines:
while (input[0] != '0') { if (input[0] == 0){ return -1; }
When taking input for a string, why are prompting users to enter a 0 to end it?
strrchr returns the pointer from where the searched character begins. So, you can that itself to determine where the '+' symbol is and two split the strings instead of your while loop. See strrchr man page
Also, your idea of adding characters is not clear. From your example, it appears you are considering a = 1, b = 2 etc. In such a case, if your code is case insensitive, then you can convert all your input to upper case and then do (input[0] - 'A')+1 to convert your letters like a, b, c to 1, 2, 3 etc.
Hope these pointers help. Suggest you check your problem statement again and refactor your code accordingly.

Resources