Program skipping some lines when trying to read - c

I'm trying to read this kinda of file
0 //Lonely number that represents the turn of a game
0 0 3 1 2 2
0 1 0 0 3 0
0 2 9 2 0 1
0 3 11 2 3 1
1
4 6 7 8 5 6
3 5 6 7 7 8
1 4 5 6 9 6
4 5 7 6 5 4
but in my code, everytime i try to detect a new line, the program just take a complety random line and write
while( fgets(line,255,*save) != NULL){
printf("The line says: %s",line);
if(line[0] =='\n'){
//the pointer is because the file was passed to a function
fscanf(*save, "%*[^\n]\n"); //To skip this new line and get the one integer
fscanf(*save,"%d",&turno); //get the lonely number
printf("Turno: %d\n",turno);
getch();
}
fscanf(*save,"%d %d %d %d %d %d",&player,&pilha,&id,&x,&y,&qtd); //Get the integers from each line
printf("%d %d %d %d %d %d\n",player,pilha,id,x,y,qtd);
}

Related

How to fill in blank (integer) places with zero in C?

I want to add a leading zero in a C integer. I am making a clock. Here is the code I have so far:
int main(){
while (1){
time_t present;
time(&present);
struct tm *myTime = localtime(&present);
printf("%2d:%2d:%2d\n", myTime->tm_hour,myTime->tm_min, myTime->tm_sec);
sleep(1);
}
return 0;
}
Here is the current output:
11:30: 0
11:30: 1
11:30: 2
11:30: 3
11:30: 4
11:30: 5
11:30: 6
11:30: 7
11:30: 8
11:30: 9
11:30:10
Here is the output I want:
11:30:00
11:30:01
11:30:02
//and so on...
Fill a 0 betwen the % and the length modifier, here 2, at each format specifier in the printf() call:
printf("%02d:%02d:%02d\n", myTime->tm_hour,myTime->tm_min, myTime->tm_sec);
| | |
here here here

Null distribution of Rank tests

I need to compute the distribution of a test statistic in C. The test statistic is based on ranks. So rather than generating observations and rank them I think I can use natural numbers and there all possible distinct combinations for my computation. So i have written a code in C. But it is not displaying the expected output, just some symbols I suppose. When I ran it in an online compiler it displayed a Segmentation fault. Please help me rectify the errors. Any suggestions will be appreciated. The following is the code that I have written.
#include<stdio.h>
#include<conio.h>
void main()
{
int i1,i2,i3,j1,j2,j3,i,k,p,m1,n1,combo1,combo2,combo3;
int fcombo1=0, fcombo2=0, fcombo3=0;
m1=3;
n1=3;
p=1;
int factorial(int n,int r);
for(i1=1;i1<=6;i1++)
for(i2=i1+1;i2<=6;i2++)
for(i3=i2+1;i3<=6;i3++)
for(j1=1;j1<=6;j1++)
if(j1!=i1&&j1!=i2&&j1!=i3)
for(j2=1;j2<=6;j2++)
if(j2!=i1&&j2!=i2&&j2!=i3&&j2>j1)
for(j3=1;j3<=6;j3++)
if(j3!=i1&&j3!=i2&&j3!=i3&&j3>j2)
{
for(i=1;i<=3;i++)
for(k=0;k<=1;k++)
{
if(i==1)
{
combo1=factorial(i-1,1)*factorial(m1-1,p)*factorial(i1-i,p-k)*factorial(n1-i1+i,p+k+1);
fcombo1=fcombo1+combo1;
}
else if(i==2)
{
combo2=factorial(i-1,p)*factorial(m1-1,p)*factorial(i2-i,p-
k)*factorial(n1-i2+i,p+k+1);
fcombo2=fcombo2+combo2;
}
else if(i==3)
{
combo3=factorial(i-1,p)*factorial(m1-1,p)*factorial(i3-i,p-
k)*factorial(n1-i3+i,p+k+1);
fcombo3=fcombo3+combo3;
}
printf("%3d%3d%3d%3d%3d%3d%3d%3d%3d\n",i1,i2,i3,j1,j2,j3,
fcombo1,fcombo2,fcombo3);
}
}
getch();
}
int factorial(int n,int r)
{
if(n<r)
return(0);
else if(n==r)
return(1);
else if(r==1)
return(n);
else
return(factorial(n-1,r)+factorial(n-1,r-1));
}
Output:
1 2 3 4 5 6 0 0 0
1 2 3 4 5 6 0 0 0
1 2 3 4 5 6 0 0 0
1 2 3 4 5 6 0 2 0
1 2 3 4 5 6 0 2 0
1 2 3 4 5 6 0 2 4
1 2 4 3 5 6 0 2 4
1 2 4 3 5 6 0 2 4
1 2 4 3 5 6 0 2 4
1 2 4 3 5 6 0 4 4
1 2 4 3 5 6 0 4 8
Segmentation fault
First of all, the way you design the program uses 10 levels of for loops, it is usually a terrible idea to do that, think about how you can refactor it.
Second, for the specific problem, it lies in the factorial function, if r goes to less than 0, e.g. for the case of factorial(1, 0), the function will recurse infinitely, because none of the termination condition matches. As a result, the program aborted by segfault because of stack overflow in the function. So depending on how you need to calculate, add a terminate condition in the function, for example:
int factorial(int n,int r)
{
if(n<r)
return(0);
else if(n==r)
return(1);
else if(r<=1)
return(n);
else
return(factorial(n-1,r)+factorial(n-1,r-1));
}
or
if (r <= 0) abort(); // this should never happen
I just wanted to know why i am getting a segmentation fault....
I guess the reason is because of Stack Overflow. You are calling a recursive function factorial within a 8 levels of nesting. so this will be in the millions of calls.
Each time you call a function, some memory is allocated in the stack. Over millions of nested calls, the stack will overflow and cause a segmentation fault

MPI IO - MPI_FIle_seek - How to calculate correct offset size for shared file

Update. Now the junk is removed from the end of the shared file, but ther is still som "junk" in the middle of the file where process 0 ends writing and process 1 starts writing:
10 4 16 16 0 2 2 3 1 3 4 2 4 5 1 0 4 6 2 8 5 3 8 10 4 9 5 4 ^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#^#10 4 16 16 1 2 6 0 3 5 2 2 2 8 1 5 6 5 6 6 4 8 9 7 6 2 1 3 6 4 10 2 5 7 7 6 10 6 5 9 9 10 6 7 5 8
However if i count the the jiberish, i get to 40. When i try to do;
offset = (length-40)*my_rank;
It works, but it is not a very scalable and robust solution. Therfor i need to compute this number for a more generell solution. Does anybody see how can be done, here is my current function:
#define MAX_BUFF 50
int write_parallel(Context *context, int num_procs, int my_rank, MPI_Status status){
int written_chars = 0;
int written_chars_accumulator = 0;
int n = context->n;
void * charbuffer = malloc(n*MAX_BUFF);
if (charbuffer == NULL) {
exit(1);
}
MPI_File file;
MPI_Offset offset;
MPI_File_open(MPI_COMM_WORLD,"test_write.txt",
MPI_MODE_CREATE|MPI_MODE_WRONLY,
MPI_INFO_NULL, &file);
written_chars = snprintf((char *)charbuffer, n*MAX_BUFF, "%d %d %d %d\n", n, context->BOX_SIDE, context->MAX_X, context->MAX_Y);
if (written_chars < 0){ exit(1); }
written_chars_accumulator += written_chars;
int i,j;
for(i=0;i<n;i++){
if(context->allNBfrom[i]>0){
written_chars = snprintf((char *)charbuffer+written_chars_accumulator, (n*MAX_BUFF - written_chars_accumulator), "%d %d %d ", i, context->x[i], context->y[i]);
if (written_chars < 0){ exit(1); }
written_chars_accumulator += written_chars;
for(j=0;j<context->allNBfrom[i];j++){
written_chars = snprintf((char *)charbuffer+written_chars_accumulator, (n*MAX_BUFF - written_chars_accumulator), "%d ", context->delaunayEdges[i][j]);
if (written_chars < 0){ exit(1); }
written_chars_accumulator += written_chars;
}
written_chars = snprintf((char *)charbuffer+written_chars_accumulator, (n*MAX_BUFF - written_chars_accumulator), "\n");
if (written_chars < 0){ exit(1); }
written_chars_accumulator += written_chars;
}
}
int length = strlen((char*)charbuffer);
offset = (length-40)*my_rank; //Why is this correct? the constant = 40 needs to be computet in some way...
//printf("proc=%d:\n%s",my_rank,charbuffer);
MPI_File_seek(file,offset,MPI_SEEK_SET);
MPI_File_write(file,charbuffer,length,MPI_CHAR,&status);
MPI_File_close(&file);
return 0;
}
Her is my current result, with this solution which is also correct: 10 4 16 16 0 2 2 3 1 3 4 2 4 5 1 0 4 6 2 8 5 3 8 10 4 9 5 4 10 4 16 16 1 2 6 0 3 5 2 2 2 8 1 5 6 5 6 6 4 8 9 7 6 2 1 3 6 4 10 2 5 7 7 6 10 6 5 9 9 10 6 7 5 8
But it will not scale because, I dont know how to compute number of jiberish elemtens. Does anybody have a clue ?
If I understand your code your goal is to remove the NULL-chars in between your text blocks. In this parallel writing approach there is no way to solve this without violating the safe boundaries of your buffers. None of the threads now how long the output of the other threads is going to be in advance. This makes it hard (/impossible) to have dynamic ranges for the write offset.
If you shift your offset then you will be writing in a aria not reserved for that thread and the program could overwrite data.
In my opinion there are two solutions to your problem of removing the nulls from the file:
Write separate files and concatenate them after the program is finished.
Post-process your output-file with a program that reads/copy chars form your output-file and skips NULL-bytes (and saves the result as a new file).
offset = (length-40)*my_rank; //Why is this correct? the constant = 40 needs to be computet in some way...
The way you compute this is with MPI_Scan. As others have pondered, you need to know how much data each process will contribute.
I'm pretty sure I've answered this before. Adapted to your code, where each process has computed a 'length' of some string:
length = strlen(charbuffer);
MPI_Scan(&length, &new_offset, 1, MPI_LONG_LONG_INT,
MPI_SUM, MPI_COMM_WORLD);
new_offset -=length; /* MPI_Scan is inclusive, but that
also means it has a defined value on rank 0 */
MPI_File_write_at_all(fh, new_offset, charbuffer, length, MPI_CHAR, &status);
The important feature of MPI_Scan is that it runs through your ranks and applies an operation (in this case, SUM) over all the preceding ranks. Afte r the call, Rank 0 is itself. Rank 1 holds the sum of itself and rank 0; rank 2 holds the sum of itself, rank 1 and rank 0... and so on.

Incorrect output with counting and tallying bits in C

This is only my 2nd programming class. There are 30 rooms. We have to see what is in each room and tally it. I already used the for loop to go through the 30 rooms and I know I have tried to use a bit counter to see what is in each room. I am not getting the correct sample output after I redirect the sample output. When I printf("%d", itemCnt[loc]);, my output is 774778414trolls
When I printf("%d", itemCnt[0]);, my output is 0trolls. I'm just trying to get one output right so I can figure out how to get the rest of the 8 outputs. From the sample output, the first number is supposed to be 6, followed by 6, 1, 4, 4 ... and so on. Below are sample inputs/outputs and what I have so far in code.
Sample input:
1 20 ##
2 21 #A
3 22 ##
4 23 #1
5 22 ##
6 22 ##
7 22 ##
8 22 ##
9 23 #Z Here be trolls � not!
10 23 #+
12 23 ##
13 24 ##
11 22 ##
14 22 #2
15 21 #1
16 20 ##
17 19 ##
18 20 ##
19 19 ##
20 18 ##
21 17 #*
22 16 #*
23 15 #%
0 14 #7
0 gold_bar
1 silver_bar
2 diamond
3 copper_ring
4 jumpy_troll
5 air
6 angry_troll
7 plutonium_troll
Sample Output:
6 gold_bar
6 silver_bar
1 diamond
4 copper_ring
4 jumpy_troll
8 air
15 angry_troll
0 plutonium_troll
code
int main()
{
// contains x and y coordinate
int first, second;
char third[100];
char fourth[100];
char Map[30][30];
// map initialization
for(int x=0; x<30; x++){
for(int y=0; y<30; y++){
Map[x][y] = '.';
}
}
while(scanf("%d %d %s",&first, &second, third) != -1) {
// Condition 1: a zero coordinate
if (first==0 || second==0) exit(0);
// Condition 2: coordinate out of range
if (first<0 || first>30 || second<0 || second>30){
printf("Error: out of range 0-30!\n");
exit(1);
}
Map[second-1][first-1] = third[1];
fgets(fourth, 100, stdin);
// bit counter
int itemCnt[8] = {0}; // array to hold count of items, index is item type
unsigned char test; // holds contents of room.
int loc;
for(loc = 0; loc < 8; loc++) // loop over every bit and see if it is set
{
unsigned char bitPos = 1 << loc; // generate a bit-mask
if((test & bitPos) == bitPos)
++itemCnt[loc];
}
// print the map
for(int h=0; h<30; h++){
for(int v=0; v<30; v++){
printf("%c", Map[h][v]);
}
printf("\n");
}
// print values
printf("%d", itemCnt[0]);
}
return 0;
}
test is not initialized. It looks like you intended to assign 'third[1]' to test.
Also, 774778414 = 0x2E2E2E2E in hex, and 0x2E is the numeric value of ASCII '.', your initial value for map locations. (Tip: when you see wild decimals like that, try Google. I entered, "774778414 in hex" without the quotes.)
I would also suggest breaking down the code into two functions: the first reads from stdin to populate Map (like you do), and the second reads from stdin to populate 8 C strings to describe your objects. It's important to note, the first loop should not go until end of input, because your posted input continues with descriptions, not strictly 3 fields like the beginning.

Read integers from file and ignore whitespace in C

I'm learning C, and part of a program I'm writing in C is to check whether my txt file contains less than or more than 81 values, and if all of the values are integers. I use fscanf to read value from file, but it also reads whitespace. How can I ignore whitespaces and make it read only integers or characters?
My code returns 162, which contains 81 integers and whitespaces.
This is the txt file:
1 2 3 4 5 6 7 8 9
2 3 4 5 6 7 8 9 1
3 4 5 6 7 8 9 1 2
4 5 6 7 8 9 1 2 3
5 6 7 8 9 1 2 3 4
6 7 8 9 1 2 3 4 5
7 8 9 1 2 3 4 5 6
8 9 1 2 3 4 5 6 7
9 1 2 3 4 5 6 7 8
#include<stdio.h>
int main() {
FILE * input_values;
input_values = fopen("text.txt","r");
if (input_values == NULL) {
fprintf(stderr, "Error! Could not open file.\n");
}
int ch, counter = 0;
ch = fscanf(input_values, "%d");
while (ch != EOF) {
counter++;
ch = fscanf(input_values, "%d");
}
printf("num %i",counter);
fclose(input_values);
}
You need to pass in an output variable for fscanf, I'm surprised your code isn't crashing:
int num;
fscanf(input_values, "%d", &num);
It works as expected if you change both your fscanf's

Resources