I'm trying to write a little program that read from a file. I tryied this codes from a file (random.dat) that contains the following numbers:
0.575 0.235
0.456 0.322
The code that I wrote is the following:
#include <stdio.h>
#include <stdlib.h>
#define N 2
int main (void) {
FILE *fp;
int i, j;
double x,y,data[N][N] = {{0}};
if ((fp = fopen("random.dat", "r")) == NULL ) {
printf("Error\n");
exit(EXIT_FAILURE);
}
fp = fopen("random.dat","r");
printf("\n");
for (i=0;i<N;i++){
fscanf(fp,"%lf",&x);
for(j=0;j<N;j++){
fscanf(fp,"%lf",&x);
data[i][j] = x;
printf("data[%d][%d]=%lf\n",i,j,data[i][j]);
}
}
printf("\n");
fclose(fp);
return(0);
}
Does the code is well written?
I don't understand why the terminal write:
data[0][0]=0.235000
data[0][1]=0.465000
data[1][0]=0.322000
data[1][1]=0.322000
Instead of:
data[0][0]=0.575000
data[0][1]=0.235000
data[1][0]=0.465000
data[1][1]=0.322000
Any idea? Thanks!
In this nested loop (reformatted to be easier to read):
for (i=0; i<N; i++)
{
fscanf(fp, "%lf", &x); // first fscanf
for(j=0; j<N; j++)
{
fscanf(fp, "%lf", &x); // second fscanf
data[i][j] = x;
printf("data[%d][%d]=%lf\n", i, j, data[i][j]);
}
}
You'll see that the inner loop immediately overwrites the x value read in your outer loop. That means you essentially skip reading the first number in the file entirely. Later that causes one of the inner-loop fscanf calls to fail, but since you don't check the return value, your program doesn't notice.
Just delete the first fscanf() line and you'll be set.
As an editorial aside, if you step through your program with a debugger, you'd see this problem happening immediately.
replace statements,
for (i=0;i<N;i++){
fscanf(fp,"%lf",&x);
for(j=0;j<N;j++){
fscanf(fp,"%lf",&x);
data[i][j] = x;
printf("data[%d][%d]=%lf\n",i,j,data[i][j]);
}
}
with
for (i=0;i<N;i++){
for(j=0;j<N;j++){
fscanf(fp,"%lf",&x);
data[i][j] = x;
printf("data[%d][%d]=%lf\n",i,j,data[i][j]);
}
}
Related
I'm new to C and need some help to understand how this piece of code works. I know that it reads the values that the user writes, puts them into an array, and then prints them out.
But I don't understand why I need two "counters" (i and j) to do this. Can someone help me to figure it out?
#include<stdio.h>
int main ()
{
int A[5];
int i=0;
int j=0;
while (i < 5)
i++;
printf("Enter your %d number\n", i);
scanf("%d", &A[i]);
}
while (j < 5)
{
j++;
printf ("\n%d\n", A[j]);
}
}
Technically, what you have aren't two counters, but two loops. If you wanted, to, you could just reuse i for the second loop as well, by doing something like this:
while (i < 5)
i++;
printf("Enter your %d number\n", i);
scanf("%d", &A[i]);
}
i = 0;
while (i < 5)
{
i++;
printf ("\n%d\n", A[i]);
}
As for why you have two loops, the reason is simple. The first loop (using i in your code), reads the 5 integers into the array A. After the first loop concludes, your array A holds the 5 int values, which you could've used however you wanted. In your case, you want to print those values. So what you do is use a loop for looping over the array elements and printing the values to the screen, one by one.
You don't need it, you can simply reset the first and reuse it. However you must increment your index only after having using it otherwise you will overflow the limit of the array :
#include<stdio.h>
int main ()
{
int A[5];
int i=0;
while (i < 5) {
printf("Enter your %d number\n", i);
scanf("%d", &A[i]); // the last must be 4 not 5
i++; //<== increment here
}
i=0;
while (i < 5)
{
printf ("\n%d\n", A[i]); //idem
i++;
}
}
I am attempting to create a text file using C that will contain a table of values in Fahrenheit and their Celsius conversion.
I am able to use fprintf properly outside of the for loop but when I put it inside it does not print anything to the file. The code compiles properly but when I try to execute it completes but with exit code "-1073741819"
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
int main()
{
FILE *filePointerThree;
double myArray[100];
filePointerThree = fopen("myFileFive.txt", "w");
for(int i=0; i<=100; i++)
{
myArray[i] = (i-32)/1.8;
}
for(int j=0; j<=100; j+=5)
{
fprintf(filePointerThree, "%d degrees F \t %5.2lf degrees C\n", j, myArray[j]);
}
fclose(filePointerThree);
}
Your array needs to be larger to hold 101 values (0 through 100):
double myArray[101];
Upon further review, the code can be simplified to not require an array, as follows. A return 0; at the end of main() will ensure an exit code of 0. Minor: the math.h and stdlib.h includes are not required as fopen() and friends are defined in stdio.h.
#include <stdio.h>
int main()
{
FILE *filePointerThree;
filePointerThree = fopen("myFileFive.txt", "w");
for(int j=0; j<=100; j+=5)
{
fprintf(filePointerThree, "%d degrees F \t %5.2lf degrees C\n", j, (j-32)/1.8);
}
fclose(filePointerThree);
return 0;
}
I'm creating a prog for my exam. The code works properly but i got Time Limit error. How I can write this code bettere to avoid this error?
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
int main()
{
int a, sum;
float b, i;
i=0;
sum=0;
FILE *file1;
file1=fopen("input.txt","w");
do{
fscanf(file1, "%d", &a);
if(a!=0){
sum=sum+a;
i++;
}
} while(a!=0);
fclose(file1);
b=(sum/i);
printf("%f", b);
FILE *file2;
file2=fopen("output.txt","w");
fprintf(file2, "%f", b);
fclose(file2);
return 0;
}
This code is a potential problem:
do{
fscanf(file1, "%d", &a);
if(a!=0){
sum=sum+a;
i++;
}
} while(a!=0);
You don't check the return value from fscanf(), so when you hit the end of the input file, if the last value you read is non-zero, your code will go into an infinite loop.
A better solution:
do{
int numScanned = fscanf(file1, "%d", &a);
// break loop if fscanf() fails for any reason
if ( numScanned != 1 ) break;
if(a!=0){
sum=sum+a;
i++;
}
} while(a!=0);
You can remove fscanf(file1, "%d", &a); from do while there is no use of it because you are opening input.txt file in "w" mode so it will truncate and considered as new empty file. so, it don't have any content inside it. this way time complexity will be reduced.
I create it a program that asks for raw and columns after that asks you to put numbers to the dimensional array. This arrays inputs to a file. When i open the file i can't see the array.
#include <stdio.h>
#include <stdlib.h>
#include <curses.h>
int main () {
FILE *fp;
int n,m;
int i,j;
float b;
char filename[100];
int getfloat(float *);
printf("Number of rows\n");
scanf("%d",&n);
printf("Number of colums\n");
scanf("%d",&m);
float s[n][m];
for (i=1;i<=n;i++)
{
for (j=1;j<=m;++j)
{
printf("Insert number %d",i);
printf(",%d\n", j);
scanf("%f",&b);
s[i][j]=b;
}
}
printf("Enter file name \n");
scanf("%s", filename);
// ****print file****
fp=fopen(filename,"w+");
if(fp!=NULL)
{
fputs(s,fp);
fprintf("%c",s);
}
fclose(fp);
return 0;
the only thing i see is this
If you want a list of numbers, probably in some kind of grid in the file, then at the minimum you want a loop such as the following:
for (int i=0; i<n; ++i)
{
for (int j=0; j<m; ++j)
{
fprintf(fp, "%f ", s[i][j]);
}
fprintf(fp, "\n");
}
See fprintf for documentation on the format specifiers; you'll probably want to tweak that to get better-looking values.
Also, again, note that arrays start from 0. Your initial read loop skips the very first element, and writes past the end of the actual array.
fprintf("%c", s); and fputs does not print out the contents of the array, it prints out the location stored in the array's pointer and tries to interpret it as a char. What you would need to print out the proper values is to loop through each value and use fprintf with each float value, using s[i][j] similar to how you initialized it.
The way you initialized the array is also off, as arrays begin at 0, not 1. Currently your for loop does not ever access s[0][0] or s[1][0] and so on. Your for loops should have i initialized to 0, and have the condition be i < n instead of i<=n.
Hello everyone,
I decided some time ago to write my own version of Minesweepers as some practice and I did it. The game ran perfectly, but after deciding to add a "Choose difficulty" option the window freezes and I get an error message, saying that the program does not respond. Also the line 0xC0000005 appeares. I have tryed many, many things: moving code from main() to a seperate function(now all in int playGame()), allocating some more memory in the heap, even creating a seperate .c file to store some piece of the code, but nothing worked sofar. I came back to the code after a few weeks, but I still have no clue why it is happening.
Can anyone help me with this? I hope my code is not hard to read. I added some comments explaining what is what. I am still new to C.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "difLvl.c"
int displayFiled(char **field); //prints out the map of the field
int combine(char answer, int answer1); //combines user input and field numeration
int Randomizer(int **mineArray); //generates random mine map
int difficulty();
int playGame();
int main(){
int playGame();
playGame();
system("PAUSE");
return 0;
}
int Randomizer(int **mineArray){
int difficulty();
int i, j;
srand(time(NULL));
int mines;
int placeMine;
int totalMines;
//int difLvl=2;
int difLvl=difficulty();
for(i=0, totalMines=0; i<10; i++){
for(j=0, mines=0; j<10 && mines<difLvl; j++){
placeMine= rand() % 2;
mineArray[i][j] = placeMine;
if(placeMine==1){
++mines;
};
};
totalMines+=mines;
};
return totalMines;
}
int displayFiled(char **field){
int i, j;
printf(" A B C D E F G H I J\n");
printf(" --------------------\n");
for (i=0; i<10; i++){
if (i==9){
printf("%d |", i+1);
}else{
printf("%d |", i+1);
};
for (j=0; j<10; j++){
printf("%c ", field[i][j]);
if (j==9){
printf("\n");
};
};
};
printf("\n");
return 0;
}
int playGame(){
int displayFiled(char **field);
int combine(char answer, int answer1);
int Randomizer(int ** mineArray);
char Y_char; //column as character (a, b, c etc.)
int X; //row
int Y; //Y_char converted to a number
int **mineArray; //stores the map of mines
char **fieldDisplay; //prints out the map of the field
int i, j; //counters
int life=1;
int movePl=0; //no dying on the first move
int globalMines; //number of mines placed
int openedFields=0; //counts the number of fields opened
//int difLvl;
//int difficulty();
//difLvl= difficulty();
/*disabled the trhee lines above while I was trying some solutions*/
/*int difficulty() is now called from int Randomizer()*/
system("cls");
/*Allocates memory to mineArray*/
mineArray= (int*)calloc(10, sizeof(int));
for(i = 0; i < 10; i++){
mineArray[i] = calloc(10, sizeof(int));
};
/*Allocates memory to fieldDisplay*/
fieldDisplay= (int*)calloc(10, sizeof(int));
for(i = 0; i < 10; i++){
fieldDisplay[i] = calloc(10, sizeof(int));
};
/*default look of fields with ?*/
for (i=0; i<10; i++){
for (j=0; j<10; j++){
fieldDisplay[i][j]='?';
};
};
globalMines= Randomizer(mineArray);
while(life==1 && openedFields<(100-globalMines)){
/*for checking purposes only*/
/*for (i=0; i<10; i++){
for (j=0; j<10; j++){
printf("%d ", mineArray[i][j]);
if (j==9){
printf("\n");
};
};
};*/
//printf("\nDifficulty level %d\n", difLvl);
printf("Total number of mines is %d\n\n", globalMines);
printf("\tMove nr. %d\n\n", movePl+1);
displayFiled(fieldDisplay);
printf("Which field do You want to activate?\nType first the letter, space and then the number (A 1, B 10 etc.)\n");
scanf("%c %d", &Y_char, &X);
if (Y_char >= 'A' && Y_char <= 'Z'){
Y = Y_char - 'A';
}else if(Y_char >= 'a' && Y_char <= 'z'){
Y = Y_char - 'a';
};
/*checks if a field is a mine*/
/*X-1 because the player chooses from 1 to 10*/
if (mineArray[X-1][Y]==0 && fieldDisplay[X-1][Y]=='?'){
movePl++;
fieldDisplay[X-1][Y]='0';
openedFields=openedFields+1;
OPEN : if (((X-2)<10) && ((X-2)>=0)){
if (mineArray[X-2][Y]==0 && fieldDisplay[X-2][Y]=='?'){
fieldDisplay[X-2][Y]='0';
openedFields=openedFields+1;
};
};
if ((X<10) && (X>=0)){
if (mineArray[X][Y]==0 && fieldDisplay[X][Y]=='?'){
fieldDisplay[X][Y]='0';
openedFields=openedFields+1;
};
};
if (((Y+1)<10) && ((Y+1)>=0)){
if (mineArray[X-1][Y+1]==0 && fieldDisplay[X-1][Y+1]=='?'){
fieldDisplay[X-1][Y+1]='0';
openedFields=openedFields+1;
};
};
if (((Y-1)<10) && ((Y-1)>=0)){
if (mineArray[X-1][Y-1]==0 && fieldDisplay[X-1][Y-1]=='?'){
fieldDisplay[X-1][Y-1]='0';
openedFields=openedFields+1;
};
};
system("cls"); //clears console screen
}else if (mineArray[X-1][Y]==0 && fieldDisplay[X-1][Y]=='0'){
system("cls");
printf("You can't choose an already opened field!\n\n");
}else if(mineArray[X-1][Y]==1 && movePl==0){
/*only activates on the first turn if players hits mine*/
movePl++;
mineArray[X-1][Y]= 0;
fieldDisplay[X-1][Y]='0';
globalMines=globalMines-1;
goto OPEN;
system("cls");
}else{
system("cls");
printf("YOU DIED ! YOU DIED ! YOU DIED !\n\n");
printf("Moves successfully made: %d\n\n", movePl-1);
fieldDisplay[X-1][Y]='1';
displayFiled(fieldDisplay);
--life;
};
};
if(openedFields==(100-globalMines)){
printf("Congratulations! You won the game!\n\n");
displayFiled(fieldDisplay);
};
for(i = 0; i < 10; i++){
free(mineArray[i]);
};
free(mineArray);
for(i = 0; i < 10; i++){
free(fieldDisplay[i]);
};
free(fieldDisplay);
return 0;
}
The difLvl.c file:
#include <stdio.h>
#include <stdlib.h>
int difficulty(){
int difLvl;
while(1){
printf("Please choose a difficulty level:\n");
printf("Easy-1\nNormal-2\nNightmare-3\n");
printf("Your answer: ");
scanf(" %d", &difLvl);
if(difLvl>=1 && difLvl<=3){
break;
}else{
system("cls");
continue;
};
};
system("cls");
return difLvl;
}
I created it, because I thought that maybe main() had too many code in it and that maybe that was why the difficulty option wasnt working right.
EDIT
After the user is promped to enter the difficulty level, the mine map is created, but after choosing a filed, the program crashes.
SOLVED
scanf("%c %d", &Y_char, &X);
changed to
scanf(" %c %d", &Y_char, &X);
First, you don't allocate your two-dimensional fields correctly. The "outer" field must hold int *, not just int:
mineArray = calloc(10, sizeof(*mineArray));
for (i = 0; i < 10; i++) {
mineArray[i] = calloc(10, sizeof(*mineArray[i]));
}
Another potential source of the segmentation fault is that Y might end up uninitialised and therefore with a garbage value. The cause is the scanf:
scanf("%c %d", &Y_char, &X);
Most scanf formats skip white space before the conversion, but %c doesn't. It is very likely that you read the newline character as the char for %c when you expect to read a letter. Because the new-line character is white space, you can hot-fix the by placing a space before the %c? format:
scanf(" %c %d", &Y_char, &X);
(I say hot-fix, because it isn't a good solution. scanf doesn't treat new-line characters specially; they are just space. A better solution might be to read a line first with fgets and then scan that with sscanf. At least you can treat each line as frash input. (And your input really should ensure that bad input is ignored.)
Lastly, it is strange that you include a *.c file. If you want to spread ypur project over various files, which is basically a good idea, you should write a header file for each *.c, which has the file's interface. Include the header files in other *.c files; compile the *.c files into objects separately and then link them. This process is usually controlled by Makefiles or Projects.