Code working on DEvC++ and Ideone but not on competetion website - c

This code works on DEVCPP and IDEONE but is not accepted by the website where this question is.
It is an on-line competition where the in built compiler is saying: COMPILATION FAILED.
This is a program which finds str2 in str1 and returns index of sub-string if found. Else prints -1.
I know using GOTO is not recommended. :( Sorry for this. Cant figure out a way for this.
IDEONE link: LINK
Code is:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int main()
{
char s1[19], s2[19],*p,c,d,k=0;
int i;
gets(s1); gets(s2);
p = strstr(s1,s2);
if( (strlen(s2) > strlen(s1)) || !p )
{printf("-1");goto ex;}
for(i=0;i<strlen(s1); i++)
{
c = s1[i];
d = s1[i+1];
if(c == s2[k] && d == s2[k+1])
{
printf("%d", i);
goto ex;
}
}
ex:
return 0;
}

a.c:15:14: error: comparison between signed and unsigned integer expressions
Make i unsigned.
a.c:19:9: error: array subscript has type 'char'
Make k int.
Notes:
Use fgets instead of gets.
goto is ok in some circumstances, like the pattern you use can be used to do some default-stuff (eg logging) before return. Also for dropping out from inner loops, jump-table usage (&&), doing default: after having done one of the case x:'s, retry after case x: and a few others.

Related

Why am I getting 0.00 when I enter alphabetical character?

The following is the code that I wrote. I feel like I have missed something with the pointer or might have made mistake in the calculation. But as for as I see, everything seems good for me but when I enter, for example: hello or anything else, it gives me 0.00 as output.
The below is correct
Enter a number:
6
Your number is: 6.00
But this why?
Enter a number:
h
Your number is: 0.00
Following is the complete code:
#include <stdio.h>
#include <stdlib.h>
#define SIZE 250
float myAtof(char *string, char *error);
int main() {
char string[SIZE]; // Array declaration.
float fnum1;
char errorState=0;
printf("Enter a number:\n");
gets(string);
fnum1=myAtof(string,&errorState);
if (errorState == 0) {
printf("Your number is: %.2f \n", fnum1);
} else if (errorState == 1) {
printf("Error has been occurred due to inappropriate input!\n");
}
return 0;
}
float myAtof(char* string, char* error) {
*error != '1';
float num= 0;
float decimalFlag = 1;
int decimalNumberFound = 0;
for (int i = 0; string[i]!= '\0'; i++) {
char ch = string[i];
if (ch != '.' && (ch < '0' || ch >'9')) {
error ='1';
return 0;
}
if (decimalNumberFound == 1 && ch == '.') {
error = '1';
return 0;
} else {
num = num* 10 + (ch - '0');
if (decimalNumberFound == 1)
decimalFlag *= 10;
}
}
num = num / decimalFlag;
return num;
}
Since your myAtof routine has a parameter for reporting an error and your main routine tests the error-reporting variable, errorState, presumably you expect the program to print an error message when you enter “h” or other non-numerals, and your question is why it prints “0.00” rather than the error message.
In the function declared with float myAtof(char* string, char* error), error is a pointer, and *error is the thing it points to. So, when the code executes error = '1';, that attempts to set the pointer to '1'. It does not change the thing it points to.
When you compiled this, the compiler issued a warning message, something like “warning: incompatible integer to pointer conversion assigning to 'char *' from 'int'”. You should not have ignored that message.
The function also contains the statement *error != '1';. That statement does nothing. It says to compare the value of *error to '1' to see if they are unequal. The result of the != operator is 1 or 0 indicating whether the values are unequal or not. But the statement does nothing with that result. It is just discarded, so the statement has no effect.
Nothing in your function changes the value of *error, so the thing it points to, errorState in main, is never changed. So main does not see that an error has occurred. It evaluates errorState==0 as true and executes printf("Your number is: %.2f \n", fnum1);.
To fix this, delete the statement *error != '1'; and change the two error = '1'; statements to *error = '1';.
Additionally, change '1' to 1. Setting *error to '1' sets it to the code for the character “1”. It does not set it to the value 1, which is what errorState == 1 tests for. Typically, an error status would be either 0 or 1, not 0 or '1'.
Also change else if (errorState == 1) to else. When you have an if and else that are intended to completely select between some condition X and its alternative, you do not need a second test. With your code if (X) { … } else if (Y) { … }, the first { … } is executed if X is true, the second { … } is executed if X is false and Y is true, and neither is executed if X is false and Y is false. But it should never be the case that X is false and Y is false—you want the program always to either have a number or have an error status. There should be only two possibilities, not three. So use just else, not else if.
(Conceptually, it is a bug for the program to have errorState be something other than 0 or 1, so the program would never have both X false and Y false if it were working, and the else if would be okay. But you did have a bug, and that would cause neither { … } to be executed. Designing the code to use else instead of an unnecessary else if makes it a little more resistant to misbehaving when there is a bug. Designing programs to be robust in this way is useful.)
Also pay attention to warning messages from your compiler. Preferably, tell the compiler to treat all warnings as errors, so that your program will not compile while warning messages remain. If you are using GCC or Clang, use the -Werror switch. If you are using Microsoft Visual C++, use /WX.

Why does my palindrome function always return 1?

I'm writing a function for my homework which is supposed to tell if a given string is a palindrome or not.
Although I even tried it on paper with the word "otto", my program always returns 1.
Although this is a quite common question, I'd really like to know what I'm doing wrong instead of just copying a solution from here.
int is_palindrom(const char* palin)
{
int size = strlen(palin), i=0;
for (i=0;i<=(size/2); ++i)
{
if(palin[i] != palin[(size - i -1)])
{
return 1;
}
}
return 0;
}
Your code is correct, however please note that you may have an inverted logical expression. You are returning 1 in case of not equal, and 0 when it is. This means your function is working the opposite of "standard" C functions, where 1 evaluates to true.
Obviously, you are free to use whichever value you like to represent whatever you want. However, this can easily lead to confusion if someone else is reading your code. If bool is available, you should be using that; otherwise, you should always assume 1 is true and 0 is false.
Also, make sure to note is_palindrome takes a string and not an integer.
i.e. you must call it as is_palindrome("767") and not is_palindrome(767)
Your code does return 0 when it should. I am guessing when you read the string you pass as argument to your function, there are extra characters appended to the string, most probably a new line character. Try debugging the application or adding debug output in the function. For instance print the length of the string and the ascii codes of the characters in it.
Here is the code I used to verify it:
#include <stdio.h>
#include <string.h>
int is_palindrom(const char* palin)
{
int size = strlen(palin), i=0;
for (i=0;i<=(size/2); ++i)
{
if(palin[i] != palin[(size - i -1)])
{
return 1;
}
}
return 0;
}
int main(void) {
printf("%d", is_palindrom("otto"));
return 0;
}
Make sure your (const char *) has a "\0" at the end when you call this function.
#include<stdio.h>
#include<conio.h>
int is_palindrom(const char* jj);
int main(char *args){
int rr = is_palindrom("otto");
printf("rsult is %d", rr);
getch();
}
int is_palindrom(const char* palin)
{
int size = strlen(palin), i=0;
for (i=0;i<=(size/2); ++i)
{
if(palin[i] != palin[(size - i -1)])
{
return 1;
}
}
return 0;
}
I ran you code using above code snippet and it work fine for me.it returns 0 if palindrome is entered and 1 if entered value is not palindrome. the main part of the function is the loop
for (i=0;i<=(size/2); ++i) and the comparison if(palin[i] != palin[(size - i -1)]) the loop starts from 0 and then in condition palin[0] element and palin[4-0-1] i.e palin[3] element first o and last o in this case are mapped then the increement ++i takes place and then nest mapping of palin[second] and palin[second-last] elements happen so you can you either `++i' or 'i++'

scan string for occurrences of a character in c

I found several answers to this in C++ or C#, but none for C.
I need to know how to count the number of characters in a string. The goal is to determine whether there is a closed block (bounded by braces '{', '}') in a string. right now I have the following:
int closedBlock(char* value) {
int open = 0;
int i;
for (i = 0; i < strlen(value); i++) {
if (!strcmp("{", value[i])) {
open++;
} else if (!strcmp("}", value[i])) {
open--;
}
}
return !open;
}
but it crashes after on the first if check. I'm not really clear on why this does not work. I imagine it has something to do with bad pointers (that seems to always be the problem in C), but I can't figure it out. In addition to working code, and explanation of why mine is bad would be greatly helpful.
Thanks.
NOTE
I am aware that this simply check that the number of '{' is equal to the number of '}', and not truly that there is a properly closed block. I'll solve that problem after I solve this one.
strcmp will compare two null-terminated strings. It still baffles me that your compiler actually doesn't mutter about the second parameter being a char. If you want to compare a single character just use the equal-operator ==:
int closedBlock(char* value) {
int open = 0;
int length = strlen(value);
int i;
for (i = 0; i < length; i++) {
if (value[i] == '{') {
open++;
} else if (value[i] == '}') {
open--;
}
}
return !open;
}
Hint: If you work with gcc add -Wall -Wextra to your compiler call, it will often result in useful warnings.
I am aware that this simply check that the number of '{' is equal to the number of '}', and not truly that there is a properly closed block. I'll solve that problem after I solve this one.
Another hint here: when can there be an invalid block? If and only if the end-token } occurs without a preceding start-token {. You already have all tools for this, you're just missing another if-statement.
It's because you're trying to compare a string: "{" against a single character: value[i].
value (presumably) points to an array of characters, while value[i] specifies a single one of those. So you want to compare character-to-character like so:
for (i = 0; i < strlen(value); i++) {
if (value[i] == '{') {
open++;
} else if (value[i] == '}') {
open--;
}
}
Note the use of single quotes around the { and }. That tells the compiler it's a single character and not a C-string.
why you use strcmp() if you only compare one char?
you can simply use the == operator see my example:
http://ideone.com/dNCH2
best regards kenny

Caesar Cipher Program - Absurd Number in Array Output

I'm actually writing about the same program as before, but I feel like I've made significant progress since the last time. I have a new question however; I have a function designed to store the frequencies of letters contained within the message inside an array so I can do some comparison checks later. When I ran a test segment through the function by outputting all of my array entries to see what their values are, it seems to be storing some absurd numbers. Here's the function of issue:
void calcFreq ( float found[] )
{
char infname[15], alpha[27];
char ch;
float count = 0;
FILE *fin;
int i = 0;
while (i < 26) {
alpha[i] = 'A' + i++;
}
printf("Please input the name of the file you wish to scan:\n");
scanf("%s", infname);
fin = fopen ( infname, "r");
while ( !feof(fin) ) {
fscanf(fin, "%c", &ch);
if ( isalpha(ch) ) {
count += 1;
i = 0;
if ( islower(ch) ) { ch = toupper(ch); }
while ( i < 26 ) {
if ( ch == alpha[i] ) {
found[i]++;
i = 30;
}
i++;
}
}
}
fclose(fin);
i = 0;
while ( i < 26 ) {
found[i] = found[i] / count;
printf("%f\n", found[i]);
i++;
}
}
At like... found[5], I get this hugely absurd number stored in there. Is there anything you can see that I'm just overlooking? Also, some array values are 0 and I'm pretty certain that every character of the alphabet is being used at least once in the text files I'm using.
I feel like a moron - this program should be easy, but I keep overlooking simple mistakes that cost me a lot of time >.> Thank you so much for your help.
EDIT So... I set the entries to 0 of the frequency array and it seems to turn out okay - in a Linux environment. When I try to use an IDE from a Windows environment, the program does nothing and Windows crashes. What the heck?
Here are a few pointers besides the most important one of initializing found[], which was mentioned in other comments.
the alpha[] array complicates things, and you don't need it. See below for a modified file-read-loop that doesn't need the alpha[] array to count the letters in the file.
And strictly speaking, the expression you're using to initialize the alpha[] array:
alpha[i] = 'A' + i++;
has undefined behavior because you modify i as well as use it as an index in two different parts of the expression. The good news is that since you don't need alpha[] you can get rid of its initialization entirely.
The way you're checking for EOF is incorrect - it'll result in you acting on the last character in the file twice (since the fscanf() call that results in an EOF will not change the value of ch). feof() won't return true until after the read that occurs at the end of the file. Change your ch variable to an int type, and modify the loop that reads the file to something like:
// assumes that `ch` is declared as `int`
while ( (ch = fgetc(fin)) != EOF ) {
if ( isalpha(ch) ) {
count += 1;
ch = toupper(ch);
// the following line is technically non-portable,
// but works for ASCII targets.
// I assume this will work for you because the way you
// initialized the `alpha[]` array assumed that `A`..`Z`
// were consecutive.
int index = ch - 'A';
found[index] += 1;
}
}
alpha[i] = 'A' + i++;
This is undefined behavior in C. Anything can happen when you do this, including crashes. Read this link.
Generally I would advise you to replace your while loops with for loops, when the maximum number of iterations is already known. This makes the code easier to read and possibly faster as well.
Is there a reason you are using float for counter variables? That doesn't make sense.
'i = 30;' What is this supposed to mean? If your intention was to end the loop, use a break statement instead of some mysterious magic number. If your intention was something else, then your code isn't doing what you think it does.
You should include some error handling if the file was not found. fin = fopen(..) and then if(fin == NULL) handle errors. I would say this is the most likely cause of the crash.
Check the definition of found[] in the caller function. You're probably running out of bounds.

Averaging 3 integers

My assignment is to fix the code. I have my edited code below and the original code below that. I figure I still have a few errors in here. My error checking doesnt seem to work, and I am not sure if my getchar() function is written or working properly.
Please assume I know nothing becasue that is fairly accurate.
The code compiles, but the answer is always 2. I am about 4 hours into this piece of code with 3 more to work after this.
My code
#include <stdio.h>
double get_number(double num);
main () {
double n1,n2,n3;
double average;
printf("\nCompute the average of 3 integers\n");
printf("--------------------------------\n");
n1 = get_number(1);
n2 = get_number(2);
n3 = get_number(3);
average = (n1 + n2 + n3)/3;
printf("The average is %0.2f\n",average);
}
double get_number(double num) {
double value = 0;
char c;
int i;
printf("Please input number %d: ", num);
while (c = getchar != '\n') {
if ( (c>9) || (c<0) ) {
printf("Incorrect character entered as a number - %c\n",c);
return(0);
}
else {
value = num;
}
}
return(value);
}
Original code
#include <stdio.h>
main () {
double n1,n2,n3;
double average;
printf("\nCompute the average of 3 integers\n");
printf("--------------------------------\n");
n1 = get_number(1);
n2 = get_number(2);
n3 = get_number(3);
average = (n1 + n2 + n3)/3;
printf("The average is %0.2f\n",average);
}
double get_number(int num) {
double value = 0;
char c;
printf("Please input number %d: ", num);
while (c = getchar() != '\n') {
if ( (c<=9) && (c>=0) ) {
printf("Incorrect character entered as a number - %c\n",c);
exit(-1);
}
else {
value = 10*value + c - '0';
}
}
return(value);
}
A few issues:
1. You should be using '9' and '0', since you want the ASCII values for digit '9' (0x39) and '0' (0x30), not 0x9 and 0x0.
if ( (c>'9') || (c<'0') ) {
2. != has higher precedence than =, so you need parens. Learn operator precedence, and if you're in doubt, use parens:
3. getchar is a function not a variable.
while ((c = getchar()) != '\n') {
4. You use the wrong conversion. num is a double, so you would need %f. Or, you could make num a int.
printf("Please input number %f: ", num);
5. You never actually use c in any way (except error checking). You always return 0 or num (see your else clause), which makes no sense. The else body of the original is correct.
You got the floating point parsing all wrong and shouldn't be doing it yourself. There's an easier way:
double get_number(double num) {
double value = 0.0;
printf("Please input number %lf: ", num);
scanf("%lf", &value);
return(value);
}
The issues with the original program are:
getchar() returns an ASCII code, and the condition was wrong. When checking for boundaries, use ((c<'0') || (c>'9')).
For the exit function you need to include "stdlib.h".
For the main function to understand what is get_number, you need to either move the function to be before the main function, or you can use a forward declaration.
The assignment operator (=) has lower precedence than the inequality operator (!=), so you need to use parenthesis, like: ((c = getchar()) != '\n')
You have actually created several more issues, so I wouldn't rely on your code.
In any case, in general - it is advised you study how to use a debugger. Once your code is compiling (and for that you'll need to get accustomed to the compilation error messages), you need to start debugging your code. I suggest you take some time to learn how to set breakpoints, set watches, and go step by step into your code. That skill is absolutely essential for a good developer.
Here's how I'd go about correcting the code ...
http://ideone.com/a0UMm -- compilation errors
http://ideone.com/ljUg1 -- warnings, but it works now
http://ideone.com/Qd0gp -- no errors, no warnings, test run ok
For 1. I used the "original code" as posted by you.
For 2. I used int main(void), declared the function get_number before defining main, added parenthesis in line 20, and added #include <stdlib.h>
For 3. I added return 0; before the final } of main. I also removed the extra output that messed up the ideone interface (it looks better on an interactive interface)
Edit more tests needed to complete the task of correcting the original code

Resources