Read integers from file and ignore whitespace in C - 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

Related

Program skipping some lines when trying to read

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);
}

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

C bitmap: rotation and zoom

I'm recently checking out C for a friend having problems with it for school. As I only have learned java and C#, though it would be easy. But currently stuck on this.
I have a project reading a small bmp (512x512) image. I've managed to change some colors on it and have it rotated (both horizontal as vertical). Though I'm stuck with the -90° rotation.
1. ROTATION (512x512)
Currently I have this code (both getPixel and setPixel are my own functions):
typedef struct _bitmap {
char file_path[PATH_MAX+1];
char magic_number[3];
unsigned int size;
unsigned char application[5];
unsigned int start_offset;
unsigned int bitmapHeaderSize;
unsigned int width;
unsigned int height;
unsigned short int depth;
unsigned char* header;
PIXEL* raster;
} BITMAP;
void rotate(BITMAP* bmp) {
int i;
int j;
PIXEL* originalPixel;
BITMAP* originalBmp;
deepCopyBitmap(bmp, originalBmp);
for(j=1; j <= bmp->height; j++) {
for(i=1; i <= bmp->width; i++) {
originalPixel=getPixel(originalBmp->raster, bmp->width, bmp->height, j, i);
setPixel(bmp->raster, bmp->width, bmp->height, (bmp->width + 1 - i), j, originalPixel);
}
}
}
void deepCopyBitmap(BITMAP* bmp, BITMAP* copy) {
*copy = *bmp;
if (copy->raster) {
copy->raster = malloc(copy->height * sizeof(*copy->raster));
for (int i = 0; i < copy->height; i++) {
copy->raster[i] = malloc(copy->width * sizeof(*copy->raster[i]));
memcpy(copy->raster[i], bmp->raster[i], copy->width * sizeof(*copy->raster[i]));
}
}
}
indirection requires pointer operand ('PIXEL' (aka 'struct _pixel') invalid)
copy->raster[i] = malloc(copy->width * sizeof(*copy->raster[i]));
^~~~~~~~~~~~~~~~
indirection requires pointer operand ('PIXEL' (aka 'struct _pixel') invalid)
memcpy(copy->raster[i], bmp->raster[i], copy->width * sizeof(*copy->raster[i]));
^~~~~~~~~~~~~~~~
expanded from macro 'memcpy' __builtin___memcpy_chk (dest, src, len, __darwin_obsz0 (dest))
This correctly rotates the first diagonal part of the image, but the second part is totally wrong (having two times a part of the first diagonal).
I think the problem is, swapping pixels around and halfway I'm starting to swap already swapped pixels. So I tried to duplicate my bmp, to a original bitmap (originalBmp) and one rotated (rotatedBmp). Though I think it just copies the reference. Anyone has an idea how I create a duplicate bmp?
As example (sorry for the flue img): I want the vertical lines (left), to turn -90deg, so it becomes horizontal lines (right). Though the left diagonal part is correct. But the right part of the diagonal is incorrect copying a piece of the left diagonal. I think because it swaps pixels that are already swapped in the bmp file.
2. ROTATION (512x1024)
What happens if the height or width is the double of the other? Anyone knows how to start on this?
3. ZOOM (200%)
Anyone know how to do this? Get the center pixels of the bitmap, and make them twice at the start of the image, or is there a better/cleaner solution?
1 2 3 4 5 6 7 8 3 3 4 4 5 5 6 6
2 2 3 4 5 6 7 8 3 3 4 4 5 5 6 6
3 3 3 4 5 6 7 8 4 4 4 4 5 5 6 6
4 4 4 4 5 6 7 8 4 4 4 4 5 5 6 6
5 5 5 5 5 6 7 8 5 5 5 5 5 5 6 6
6 6 6 6 6 6 7 8 5 5 5 5 5 5 6 6
7 7 7 7 7 7 7 8 6 6 6 6 6 6 6 6
8 8 8 8 8 8 8 8 6 6 6 6 6 6 6 6
From your code it seems clear that both originalBmpand bmp are pointers to some BMP-type. So when you do originalBmp=bmp;, you just get two pointers pointing to the same BMP, i.e. they operate on the same data.
I assume you have something like
struct BMP
{
// ....
};
If that is the case you can make a copy like this:
struct BMP originalBmp = *bmp;
When using originalBmp you must use the . notation, e.g. originalBmp.raster
EDIT An alternative approach
Instead of making a copy of the original bmp you could do the rotation directly on the original. Each rotation will involve 4 locations. You can copy the 4 locations into temp variables first and then write them to their final location.
For a simple matrix it could be something like this:
#include <stdio.h>
#define WIDTH 4
// display function
void d(int t[WIDTH][WIDTH])
{
int i, j;
for (i=0; i<WIDTH;i++)
{
for (j=0; j<WIDTH; j++)
{
printf("%d ", t[i][j]);
}
printf("\n");
}
}
int main(void) {
int org[WIDTH][WIDTH];
int i, j;
// Just initialize the matrix
for (i=0; i<WIDTH;i++)
{
for (j=0; j<WIDTH; j++)
{
org[i][j] = 10 + i*5 + j;
}
}
printf("Original\n");
d(org);
// Rotate the matrix
for (j=0; j < (WIDTH/2); j++)
{
for (i=0; i < ((WIDTH+1)/2); i++)
{
int t1 = org[j][i];
int t2 = org[i][WIDTH-1-j];
int t3 = org[WIDTH-1-j][WIDTH-1-i];
int t4 = org[WIDTH-1-i][j];
org[j][i] = t2;
org[i][WIDTH-1-j] = t3;
org[WIDTH-1-j][WIDTH-1-i] = t4;
org[WIDTH-1-i][j] = t1;
}
}
printf("Rotated\n");
d(org);
return 0;
}
This will output:
Original
10 11 12 13
15 16 17 18
20 21 22 23
25 26 27 28
Rotated
13 18 23 28
12 17 22 27
11 16 21 26
10 15 20 25
Change to #define WIDTH 5 and it will output:
Original
10 11 12 13 14
15 16 17 18 19
20 21 22 23 24
25 26 27 28 29
30 31 32 33 34
Rotated
14 19 24 29 34
13 18 23 28 33
12 17 22 27 32
11 16 21 26 31
10 15 20 25 30

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.

Resources