I am solving a problem on USACO. In the problem, I have to take two strings as inputs and calculate the numerical values modulo 47. If the values are same, then GO is to be printed otherwise STAY has to be printed. The initial numerical value will be calculated by taking the product of the numerical values of the alphabets ( 1 for A and similarily 26 for Z ) and then the final number will be calculated by using modulo.
My program is being compiled withour any error and the first case is also a success. But the problem is in the second case and the way my file is being appended. The program is as follows:-
#include<stdio.h>
#include<malloc.h>
#include<string.h>
#define MAX 6
main()
{
int cal(char *ptr);
int a,b;
char *comet,*group;
FILE *fptr;
comet=malloc(6*sizeof(char));
group=malloc(6*sizeof(char));
scanf("%s",comet);
a=cal(comet);
scanf("%s",group);
b=cal(group);
fptr=fopen("ride.out","a+"); (1)
//fptr=fopen("ride.txt","a+"); (2)
if(a==b)
fprintf(fptr,"GO\n"); (3)
//printf("GO\n"); (4)
else
fprintf(fptr,"STAY\n"); (5)
//printf("STAY\n"); (6)
fclose(fptr);
return 0;
}
int cal(char *ptr)
{
int c,prod=1,mod;
while(*ptr)
{
c=(*ptr++)-'A'+1;
prod=prod*c;
}
mod=prod%47;
return mod;
}
OUTPUT:-

The first case is the set two strings:-
- COMETQ
- HVNGAT
and the second case is given in the error notification itself.
If I remove the comment symbols from (2) and put it on (1), then the program is working fine because I can see the contents of the file and they appear just as the grader system wants. It isn’t happening for the actual statement of (1). The comments of line (4) and (6) are also fine but not the line (1). I am not able figure this out. Any help?
First a few notes:
main(): a decent main is either:Using
malloc()you should always check if it returnsNULL, aka fail, or not.free()malloc’ed objects.More in detail on your code:
Signature of cal()
First line in
mainyou declare the signature forcal(). Though this works you would probably put that abovemain, or put thecal()function in entirety abovemain.Max length
You have a define
#define MAX 6that you never use. If it is maximum six characters and you read a string, you also have to account for the trailing zero.E.g. from cplusplus.com scanf:
Thus:
As it is good to learn to use
malloc()there is nothing wrong about doing it like this here. But as it is as simple as it is you’d probably want to use:instead. At least: if using
mallocthen check for success and free when done, else use static array.Safer scanf()
scanf()given"%s"does not stop reading at size of target buffer – it continues reading and writing the data to consecutive addresses in memory until it reads a white space.E.g.:
In memory we would have:
And when reading the proposed stream/string above we would not read
USACOein tocometbut we would continue reading beyond the range ofcomet. In other words (might) overwriting other variables etc. This might sound stupid but as C is a low level language this is one of the things you have to know. And as you learn more you’ll most probably also learn to love the power of it 🙂To prevent this you could limit the read by e.g. using
maximum length+[what to read]. E.g:Input data
Reading your expected result, your errors, your
(N)comments etc. it sound like you should have a input file as well as an output file.As your code is now it relies on reading data from standard input, aka
stdin. Thus you also usescanf(). I suspect you should read from file withfscanf()instead.So: something like:
The cal() function
First of, the naming. Say this was the beginning of a project that eventually would result in multiple files and thousand of lines of code. You would probably not have a function named
cal(). Learn to give functions good names. The above link about coding style gives some points. IMHO do this in small projects as well. It is a good exercise that makes it easier when you write on bigger to huge ones. Name it e.g.cprod_mod_47().Then the
modvariable (and might c) is superfluous. An alternative could be:Some more general suggestions
When compiling use many warning and error options. E.g. if using gcc say:
This is tremendous amount of help. Further is the use of tools like
valgrindandgdbinvaluable.