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;
}
Related
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.
I have a 2D array representing a sudoku grid defined like this:
int** sudoku = (int**)malloc(sizeof(int*) * 9);
for(i = 0; i < 9; i++)
sudoku[i] = (int*)malloc(sizeof(int) * 9);
I've run it through a function that iterates through every element and prints, which works fine (displays 81 zeros). But then, I hand it to another function that reads a grid from a file into this array. Here's what it looks like (with a bunch of printf statements I'm using for debugging omitted).
void readSudokuFile(char* filename, int*** grid) {
FILE* file;
int i, j, curr;
file = fopen(filename, "r");
for(i = 0; i < 9; i++) {
for(j = 0; j < 9; j++) {
fscanf(file, "%d", &curr);
*grid[i][j] = curr;
}
}
fclose(file);
}
When the function is running, it appears to read find for the first row, but when it gets to the second row and tries to insert a value into sudoku[1][0], I get a seg fault. This is what the output looks like with my printfs in:
Reading line 0...
Reading col 0... got 6
Reading col 1... got 2
Reading col 2... got 4
Reading col 3... got 5
Reading col 4... got 3
Reading col 5... got 9
Reading col 6... got 1
Reading col 7... got 8
Reading col 8... got 7
Reading line 1...
Reading col 0... got 5
Segmentation fault(core dumped)
This is the file I'm trying to read in:
6 2 4 5 3 9 1 8 7
5 1 9 7 2 8 6 3 4
8 3 7 6 1 4 2 9 5
1 4 3 8 6 5 7 2 9
9 5 8 2 4 7 3 6 1
7 6 2 3 9 1 4 5 8
3 7 1 9 5 6 8 4 2
4 9 6 1 8 2 5 7 3
2 8 5 4 7 3 9 1 6
I'm compiling using gcc with -Wall and -pedantic, and am getting no compiler warnings.
I've googled around for a few hours to no avail, I'm not exactly sure what's going wrong here. Any help would be greatly appreciated.
To avoid pointer bugs you just ran into I suggest to simplify your dynamic 2D-array allocation like this ->
int (*array) [Y] = malloc(sizeof(int[X][Y]));
Access your array like this ->
int g=array[0][0];
And set like this ->
array[0][0]=0;
That will simplify your solution a lot and you also get a continuous memory block containing your 2D-array as a bonus. That will also simplify writing and reading files as you do not need to traverse each element if you do not necessarily have to do that for other reasons.
/A
Try modify your function like this:
void readSudokuFile(char* filename, int** grid) {
// ...
grid[i][j] = curr;
}
and invoke it like this:
readSudokuFile(filename, sudoku)
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.
If I have the following text file:
1 2 3 4 5 6 7 8 9 10 YEAH
11 12 13 14 15 16 17 18 19 20 YEAH
I have to following code:
#include <stdio.h>
int main(){
int arr[5][10];
FILE* foo;
foo = fopen("help.txt", "r");
int i, j;
int temp;
while (i<5 && (fscanf(foo, "%d", &temp)) !=EOF ){
arr[i][0]= temp;
for (j=1; j<10; j++){
fscanf(foo, "%d", &temp);
arr[i][j]=temp;
}
i++;
}
for (i=0; i<2; i++){
for (j=0; j<10; j++)
printf("%d ", arr[i][j]);
printf("\n");
}
fclose(foo);
}
...and it works perfectly fine when the text file has just numbers but when I add the characters "Yeah" to the text file, the code goes crazy. How do I include them? Please explain simply as I am still very new to this. Would I used fscanf(foo, %d%*c, &temp);??? Also how would I handle the new line statement if there is one?
Thank you very much
Edit:
the e input I provided initially was
1 2 3 4 5 6 7 8 9 10
11 12 13 14 15 16 17 18 19 20.
Here everything is printed out correctly. When adding the word yeah to the text file after 10 the all the other numbers are 10 as well. Essentially it does not contain 11 12... to 20. and prints out: 1 2 3 4 5 6 7 8 9 10
10 10 10 10 10 10 10 10 10 10
It is always easier to process data like this one line at a time, rather than one "token" at a time directly against the file.
Reading in a whole line with fgets() into a suitably big buffer, gives you the opportunity to take your time and go back and forth in the parsing, since it's all just bytes in memory at that point and you no longer risk confusion due to the file having a current position which is incremented as you read.
Your example conversion doesn't work, since you need something like "n numbers followed by something that is not a number, then end of line" which I don't think can be expressed as a single simple fscanf() conversion string.
Much easier to read in the whole line, then look at it token by token "by hand". See, for instance strtok() which is kind of dangerous in general but should be fine here.
Try this:
int e;
while (i<5 && (e = fscanf(foo, "%d", &temp)) !=EOF ){
if(e==0) {
fscanf(foo, "%*[^0-9]"); // this will skip the non numeric chars
continue;
}
arr[i][0]= temp;
and
for (j=1; j<10; j++){
e = fscanf(foo, "%d", &temp);
if (e==EOF) break;
else if (e==0) {
fscanf(foo, "%*[^0-9]"); continue;
}
arr[i][j]=temp;
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?