Segmentation fault while compiling online - c

I have a problem like this:
Players generally sit in a circle. The player designated to go first says the number "1", and each player thenceforth counts one number in turn. However, any number divisible by 'A' e.g. three is replaced by the word fizz and any divisible by 'B' e.g. five by the word buzz. Numbers divisible by both become fizz buzz. A player who hesitates or makes a mistake is either eliminated.
Write a program that prints out the the pattern generated by such a scenario given the values of 'A'/'B' and 'N' which are read from an input text file. The input text file contains three space delimited numbers i.e. A, B, N. The program should then print out the final series of numbers using 'F' for fizz, 'B' for 'buzz' and 'FB' for fizz buzz.
The input is like this:
Your program should read an input file (provided on the command line) which contains multiple newline separated lines. Each line will contain 3 numbers which are space delimited. The first number is first number to divide by ('A' in this example), the second number is the second number to divide by ('B' in this example) and the third number is where you should count till ('N' in this example). You may assume that the input file is formatted correctly and is the numbers are valid positive integers. E.g.
3 5 10
2 7 15
Output:
Print out the series 1 through N replacing numbers divisible by 'A' by F, numbers divisible by 'B' by B and numbers divisible by both as 'FB'. Since the input file contains multiple sets of values, your output will print out one line per set. Ensure that there are no trailing empty spaces on each line you print. E.g.
1 2 F 4 B F 7 8 F B
1 F 3 F 5 F B F 9 F 11 F 13 FB 15
Constraints:
The number of test cases <= 20
"A" is in range [1, 20]
"B" is in range [1, 20]
"N" is in range [21, 100]
Now I wrote the following code:
#include <stdio.h>
int main(int argc, char *argv[])
{
int a,b,n,i;
int part;
/* char file[200]; */
/* scanf("%s",file); */
FILE *f = fopen(argv[1],"r");
while(fscanf(f,"%d %d %d",&a,&b,&n) == 3)
{
for ( i = 1 ; i <= n ; i++ )
{
if ( i % a == 0 && i % b == 0 )
{
printf("FB ");
continue;
}
if ( i % a == 0 )
{
printf("F ");
}
else if( i % b == 0 )
{
printf("B ");
}
else
{
printf("%d ",i);
}
}
printf("\n");
}
//printf("%d",all);
return 0;
}
When I am running the above program on my computer it is working well. But in case of online compiling and running, it is giving segmentation fault. Even the file chosen by the online compiler is not giving any error on my computer.
The file for online compiler is here:
6 14 50
15 12 53
14 2 37
15 11 67
3 8 100
12 14 30
7 12 64
19 9 97
20 11 76
16 10 76
13 13 53
1 7 65
10 13 86
3 1 60
4 17 99
8 10 51
10 12 65
10 19 70
8 17 100
16 9 52
What's wrong with my code?

The problem is here:
FILE *f = fopen(argv[1],"r");
while(fscanf(f,"%d %d %d",&a,&b,&n) == 3)
If no command line arguments are provided, argv[1] is NULL, accessing it crashes the program.
Also if a name of non-existing file is given, fopen() returns NULL. Giving it to fscanf() later also crashes.
You should add checks for argc > 1 and that f != NULL.
That aside, obviously, when compiling online, the arguments are not given correctly -- I don't know how you can resolve that.

Related

How to scan and print an array with a max of 20 variables?

In C, how do I scan an print an array of 20 numbers given by the user.
Example desired output:
Enter data: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
The data entered is: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
This is what I have so far for my loop:
for (i = 0; i <= 20; i++){
scanf("%d", &arry[i]);
}
This however keeps asking for 21 inputs before the loop terminates.
Everything is fine except that =. It means:
Run FOR-LOOP from 0 up to 20.
Which means a total of 21 values. Just remove that = and you are good to go:
for (i = 0; i < 20; i++)
{
scanf("%d", &arry[i]);
}
for (i = 0; i < 20; i++){
scanf("%d", &arry[i]);
}
We should always remember that when we are declaring an array of size n, then an array of n elements with indexes 0 to n-1 is allocated. We should not access to those memory locations which are not allocated to us , The C does not allow you to do so,your program may crash.Though your compiler may not give any error message.
It is a good practice to do this.

How to generate all the distinct numbers which can be formed by eliminating one or more digits from left and/or right end of each number

I need to read some numbers from a file and generate all the numbers which can be formed by removing 1 digit from the start and one from the end ( for each one of my numbers read ) and print them into a new file.I know how to read and print in files so my question is more about the way I should think when solving this problem.
Here is an example for this problem:
for 3457 the output should be:
457
345
34
45
57
3
4
5
7
my initial thought was to read the numbers as an array of strings using a double pointer ( assuming I know how many numbers I should read so I can dynamically allocate memory to it ) and then to work on them.
After that I though of a way to generate the numbers that are obtained by removing 1 digit from the start and one from that end ( but not simultaneously ) for that I used a for loop:
for ( i = 1, j = (strlen(p[0]) - 2); i < strlen(p[0]) - 2, j >=0; ++i, --j ) //p[0] is my first number read from the file
{
printf("\n%s", p[0] + i); //this will print the numbers 457, 57, 7
char temp[10];
strncpy(temp, p[0], j);//I copy into a new temporary string to print the numbers 345, 34, 3
temp[j] = '\0';
printf("%s", temp);
printf("\n%s", temp + i);//this will print the numbers 45,4
}
But I have no idea on how to proceed with the rest of the numbers and i simply wasn't able to find or to think of an algorithm which will print them in that order, so I would really appreciate some help on how to solve this problem
Assuming that you have the number converted to a string (e.g. using sprintf) you could do something like this:
Take the original string and remove 0 chars from the right
Remove 0 chars from the left and print
Remove 1 chars from the left and print
Remove 2 chars from the left and print
...
Remove string length - 1 chars from the left and print
Take the original string and remove 1 chars from the right
Remove 0 chars from the left and print
Remove 1 chars from the left and print
Remove 2 chars from the left and print
...
Remove string length - 1 chars from the left and print
Take the original string and remove 2 chars from the right
Remove 0 chars from the left and print
Remove 1 chars from the left and print
Remove 2 chars from the left and print
...
Remove string length - 1 chars from the left and print
The above is easy to implement using two nested for-loops. Like:
int main()
{
char str[] = "123456";
size_t len = strlen(str);
size_t i, j;
for (i = 0; i < len; i++) // i is number of chars to remove (aka not print) from right
{
for (j = 0; j < len-i; j++) // j is number of chars to remove (aka not print) from left
{
size_t z=j;
int p = 0;
while (z < (len - i))
{
printf("%c", str[z]);
z++;
p = 1;
}
if (p) printf("\n");
}
}
return 0;
}
Output:
123456
23456
3456
456
56
6
12345
2345
345
45
5
1234
234
34
4
123
23
3
12
2
1
Now if the input string is "1001" the output of the program is (comments added manually):
1001 // ok
001 // Is this valid? Or should it be 1
01 // Is this valid? Or should it be 1
1 // ok
100 // ok
00 // Is this valid? Or should it be 0
0 // ok
10 // ok
0 // ok but repeated! Is this valid?
1 // ok but repeated! Is this valid?
As you can see there may be a problem with the algorithm, e.g. leading zero and repeated numbers. If that is invalid, you'll have to
keep track of already printed numbers
avoid printing leading zeros
The following assumes that the numbers are read from the input file as strings (null-terminated character arrays) and that those strings are valid representation of base 10 integers, not necessarily in the range of an int, just only digits.
Skip the leading zeroes. I assume that a string like "0042", if not rejected, should be interpreted as the number 42, so that the output should be only 4 and 2, without any 0. strspn could be used here.
Find the length (len) of the remaining string, if it's less then two characters, return.
Loop from 1 (included) to len (excluded). That is the number of characters to be removed from the source, let's call it i.
The size of the substrings is sub_length = len - i.
Loop from 0 to i (both included) to consider all the substrings of size sub_length. E.g. from 123 we consider first 12 and 23.
If the first character of the substring is '0' and its length is greater than 1, skip the following steps, so that e.g. from 1007 we won't print 007 nor 07, only 0 and 7.
Check if the actual substring can be found in the left part of the source string that we have already considered. E.g. given 4545, after having printed 45 and 54 we would find the last 45 in 454 and skip it. A loop with functions like strncmp or memcmp may come in handy, here, more than strstr which requires null-terminated strings as parameters.
If the previous step doesn't find a duplicate, print the substring (with a loop, or using printf with the format specifier "%.*s" as explained here).
This algorithm would produce the following results:
Source: "3457"
345 457 34 45 57 3 4 5 7
Source: "1045"
104 10 45 1 0 4 5
Source: "5454"
545 454 54 45 5 4
Source: "10000"
1000 100 10 1 0
Source: "0042"
4 2

How to sum all values in a same variable?

I am working on an assignment but the code is doing some weird stuff. It is my 7th day "programming", so it might be just an obvious mistake, which I simply cannot see.
I want the program to sum all values stored in a same variable. I tried to replicate some code from here: https://stackoverflow.com/a/42166389, but it did not work as expected.
So, given a set of values -let's say 012345-, the program should take every other number -4, 2, and 0-, and sum them -giving back "6"-. And, although it does identify the digits, it does not sum them... at least properly.
I do not understand why, but it gives back 48.
I have tried different inputs, and while identifying the digits properly, in all cases the sum was wrong.
I would really appreciate any help.
Oh, and here is my code!:
#include <cs50.h>
#include <stdio.h>
#include <string.h>
int main(void) {
char c;
string number;
int length, i, sum = 0;
printf("Type card number: ");
number = get_string();
printf("Tell us how many characters long was your number: ");
length = get_int();
for (i = 1; i <= length / 2; i++) {
c = number[(strlen(number) - i * 2)];
sum = c;
printf("%c %i %s\n", c, sum, number);
}
}
Some examples:
For input 012345 and length=6, the output is:
4 52 012345
2 50 012345
0 48 012345
For input 9876543210 and length=10, the output is:
1 49 9876543210
3 51 9876543210
5 53 9876543210
7 55 9876543210
9 57 9876543210
And, just to summarize, what I want is a way of summing all the values in a same variable.
sum = c;
You are assigning ASCII value to sum.You should get the corresponding number and also add it to sum, not just assign.
4 52 012345 //52 is ASCII value of 4
2 50 012345 //50 is ASCII value of 2
0 48 012345 //48 is ASCII value of 0
Try this,
sum+=c-'0';

Using Multiples in C

I'm trying to teach myself C and have only done a few things in CodeAcademy so far. I'm pretty lacking when it comes to loops in my current online course. Let's say I wanted to use a loop to make the first 5 multiples of 1 through 10 like below.
Number 1st 2nd 3rd 4th 5th
1 1 2 3 4 5
2 2 4 6 8 10
3 3 6 9 12 15
4 4 8 12 16 20
5 5 10 15 20 25
6 6 12 18 24 30
7 7 14 21 28 35
8 8 16 24 32 40
9 9 18 27 36 45
10 10 20 30 40 50
I'm drawing a blank on how I would use loop nesting or even a single loop to do the above. Anyone have any advice on where to start, I'm not understanding this I guess.
A big part of programming is about breaking larger problems into smaller problems.
If the problem of making this table is too much for you, then break the problem into pieces. e.g.
Write a function that can print the header
Write a function capable of printing one line of the table
Write a program that uses those two functions to print the whole table
see printf description
#include <stdio.h>
int main(void){
char *field_name[] = {"Number", "1st", "2nd", "3rd", "4th", "5th" };
int field_size = 10;
int num_of_fields = 6;
int number_max = 10;
//print field_name
for(int i = 0; i < num_of_fields; ++i)
printf("%-*s", field_size, field_name[i]);
puts("");
//print numbers
for(int n = 1; n <= number_max; ++n){
printf("%-*d", field_size, n);
for(int i = 1; i < num_of_fields; ++i)
printf("%-*d", field_size, n * i);
puts("");
}
return 0;
}

Error reading test cases from a file in C

for a programming homework, I'm implementing Prim's algorithm, the format of the input file for test cases is as follows:
The first line of input will be an integer C, which indicates the number of test cases. The first line of each test case contains two integers N and E, where N represents the number of nodes in the graph and E the number of edges, respectively. Then come E lines, each with 3 integers I, J and P, where I and J represent the nodes of an edge (undirected graphs, where 0 ≤ I, J
Although even I'm starting the code (I'm new to programming) i Don´t understand why my code only reads an entry for the test cases, What am I doing wrong?
this is the code reading the file entradaA.in:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main (int argc, char *argv []){
int testCases;
int numberNodes;
int numberEdges;
freopen("entradaA.in", "r", stdin);
int i, j, cont=1;
int total = 0;
int a, b, c;
scanf ("%d", &testCases);
for (i=0; i<testCases; ++i)
{
scanf ("%d %d", &numberNodes, &numberEdges); //Number Nodes & Edges
for (i=0; i<numberEdges; i++)
{
scanf ("%d %d %d", &a,&b,&c);//
printf ("%d %d %d\n", a, b, c);
}
printf ("Caso %d: Total Weight %d\n", cont++, total);
}
return (0);
}
The input file (entradaA.in) look something like this
2
7 11
0 1 17
0 2 10
0 6 14
1 2 6
1 3 1
2 3 4
2 6 3
3 4 7
4 6 10
4 5 2
5 6 9
6 9
0 1 30
0 2 30
1 3 22
1 5 33
2 3 20
2 4 33
3 4 15
3 5 20
5 4 20
You have the loop variable i modified inside the loop, which is generally unwanted. In this case, since i looped to 11 (the number of edges), it caused your program to terminate since 11 is not smaller than 2 (the number of test cases in the input).
You could use temporary variable (if you are using C++, thank you aardvarkk):
for (int i=0; i<testCases; ++i)
{
scanf ("%d %d", &numberNodes, &numberEdges); //Number Nodes & Edges
for (int j=0; j<numberEdges; j++)
Note that the int j could also be int i, but I wouldn't recommend it. Just use a variable with another name would be clearer. Or if you are in C, just drop the two int and use variables that are local to the function.
For more, you could read this.
Your code produced the following output on my machine. The only change I made was to declare the int values i, j etc. before the freopen call to make the code standard C.
0 1 17
0 2 10
0 6 14
1 2 6
1 3 1
2 3 4
2 6 3
3 4 7
4 6 10
4 5 2
5 6 9
Caso 1: Total Weight 0
It's definitely reading more than your test cases, so I'm not sure what the problem is?

Resources