I want to write a program to create a 2D double array from a text file. The contents and format of my file is
0,0.23645,8.457
4.125,7.102,8.102
1.036,0.547,3.2298,
Same number of row and same number of column. Each number is differentiated by one ','. Each line is differentiated by one'\n' character and at the end one comma.
#include <stdio.h>
#include<conio.h>
void main()
{
FILE *myfile
float a,data[10][10];
char ch;
int i,j;
clrscr();
myfile=fopen("E:\\input.txt", "r");
for(i = 0; i<3; i++)
{
for (j = 0 ; j<3; j++)
{
fscanf(myfile,"%f %c",&a,&ch);
printf("%f ",a);
data[i][j]=a;
}
printf("\n");
}
fclose(myfile);
printf("\n");
for(i=0;i<3;i++)
{ for(j=0;j<3;j++)
{ printf("%f ",data[i][j]);
}
printf("\n");
}
getch();
}
It is working, but not for every time. Sometimes it is giving garbage values, zeros or NAN. I don't know why the result of same code gives sometimes correct or sometimes wrong values?
In this code, I have made my number of row/column constant. But if it is unknown then how do I do? So, I have written another code.
#include <stdio.h>
#include<conio.h>
void main()
{
FILE *myfile;
float a,data[10][10];
char ch;
int i,j,line=0,target=0;
int f=getc(myfile);
clrscr();
myfile=fopen("E:\\input.txt", "r");
while (f!= EOF)
{ if(f=='\n')
line++;
f=getc(myfile);
}
//printf("%d",line);
target=++line;
//printf("%d",target);
for(i = 0; i<target; i++)
{
for (j = 0 ; j<target; j++)
{
fscanf(myfile,"%f %c",&a,&ch);
printf("%f ",a);
data[i][j]=a;
}
printf("\n");
}
fclose(myfile);
printf("\n");
for(i=0;i<target;i++)
{ for(j=0;j<target;j++)
{ printf("%f ",data[i][j]);
}
printf("\n");
}
getch();
}
But it is not at all working, everytime is giving wrong values.
Kindly help
It's done with the following code.
#include <stdio.h>
#include<conio.h>
void main()
{
FILE *myfile;
float a,data[10][10];
char ch;
int i=0,j=0,target=-1;
clrscr();
myfile=fopen("E:\\input.txt", "r");
while(1)
{
while(1)
{ fscanf(myfile,"%f %c",&a,&ch);
data[i][j]=a;
j++;
if(ch=='0')
{ target=j;
break;
}
else if(j==target)
break;
}
j=0;
i++;
if(i==target)
break;
}
fclose(myfile);
for(i=0;i<target;i++)
{ for(j=0;j<target;j++)
{ printf("%f ",data[i][j]);
}
printf("\n");
}
getch();
}
removed the EOF, rather using while loop.
Related
Im doing this exercise that requires to read a string and print out the length of each word.
Thing is supposedly we arent supposed to know how many words this sting has.
In this case for example its 4
viVa la VIDA loca
This is the part of the code i have made.
int textStats(char* filename);
int main()
{
FILE*file;
file=fopen("file","r");
if(file==NULL)
{
printf("Error in opening the file ");
exit(1);
}
textStats(file);
}
int textStats(char* filename)
{
int i,j;
int n=0;
int N=20;
char str[N];
while(fscanf(filename,"%c",&str[n])!=EOF)
{
n++;
}
for(i=0; i<n; i++)
{
printf("%c",str[i]);
}
i=j=0;
int count[]={0};
while(str[i]!='\0')
{
if(isalpha(tolower(str[i])))
{
count[j]++;
}
if(isspace(str[i])|| str[i]=='\0')
{
j++;
}
i++;
}
for(i=0;i<j;i++)
{
printf("word %d with count %d\n",i+1,count[i]);
}
}
What i dont understand why is it that if i initialize count[]={0} it will print errors but if i initialize it to count[]={0,0,0,0} it will return a correct value?
Firstly, you don't need to store each word's length in an array. You can just print them out whenever you finish reading 1 word
{
FILE*file;
file=fopen("file","r");
if(file==NULL)
{
printf("Error in opening the file ");
exit(1);
}
textStats(file);
}
int textStats(char* filename)
{
int i,j;
int n=0;
int N=20;
char str[N];
while(fscanf(filename,"%c",&str[n])!=EOF)
{
n++;
}
for(i=0; i<n; i++)
{
printf("%c",str[i]);
}
i=j=0;
int count=0;
while(str[i]!='\0')
{
if(isalpha(tolower(str[i])))
{
count++;
}
if(isspace(str[i])|| str[i]=='\0')
{
j++;
printf("word %d with count %d\n",j,count);
count = 0;
}
i++;
}
}
If you really want to store each word's length inside an array, you can explore the use of dynamically growing array
int count[]; is invalid, it's attempting to declare an array of incomplete size. int count[] = {0} creates an array matching the initializer list, in this case an array of 1 int items.
Thanks for all the answers, after the corrections the code did not work for a stupid error ... I opened both files with the same file pointer "database" ...
I've read dozens of questions like this but I can't get out of it, I'm going crazy.
The exercise that I have to do asks me to organize the items of a list in a file .txt that has elements of the type: Name Surname Age Wage, in alphabetical order according to the surname.
I have already created a function to insert the elements into the file and it works well.
I then went to the function to organize them but the process stops after the fscanf, and putting some test printf I saw that no values are assigned to the strings or that are assigned absurd numbers.
Please help ... thanks.
This is the code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define MAX 64
#define MAXFILE 100
void insert();
int fullcheck();
void sort();
typedef struct {
char name[MAX];
char surname[MAX];
int age;
double wage;
} data;
int main() {
insert();
return EXIT_SUCCESS;
}
void insert() {
char c;
int i;
data tmp;
FILE* database;
if ((fullcheck())>MAXFILE-1)
printf("Errore: database pieno.\n");
else {
database=fopen("database.txt", "a");
printf("Nome: ");
fgets(tmp.name, MAX, stdin);
tmp.name[strlen(tmp.name)-1]='\0';
printf("Cognome: ");
fgets(tmp.surname, MAX, stdin);
tmp.surname[strlen(tmp.surname)-1]='\0';
for (i=0; i<strlen(tmp.surname); i++) {
if (tmp.surname[i]==' ')
tmp.surname[i]='#';
}
printf("Eta': ");
scanf("%d", &tmp.age);
printf("Salario: ");
scanf("%lf", &tmp.wage);
while((c=getchar())!='\n');
fprintf(database, "%s %s %d %.0lf \n", tmp.name, tmp.surname, tmp.age, tmp.wage);
fflush(database); fclose(database);
if ((fullcheck())>1)
sort();
}
}
int fullcheck() {
char c;
int r=0;
FILE* database;
if ((database=fopen("database.txt", "r"))==NULL) {
return 0;
}
else {
while((c=getc(database))!=EOF) {
if(c=='\n')
r++;
}
return r;
}
}
void sort() {
char tmpstr[MAX];
int len=fullcheck(), i, a, b;
data tmp[len];
FILE* database;
FILE* sorted;
database=fopen("database.txt", "r");
database=fopen("sorted.txt", "w");
for (i=0; i<=len; i++) {
fscanf(database, "%s %s %d %lf \n", &tmp[i].name, &tmp[i].surname, &tmp[i].age, &tmp[i].wage);
}
for (a=0 ; a<(len-1); a++) {
for (b=0; b<(len-1); b++) {
if ((tolower(tmp[b].surname[0]))>(tolower(tmp[b+1].surname[0]))) {
strcpy(tmpstr, tmp[b].surname);
strcpy(tmp[b].surname, tmp[b+1].surname);
strcpy(tmp[b+1].surname, tmpstr);
}
}
}
for (a=0; a<(len-1); a++) {
fprintf(sorted, "%s %s %d %.0lf \n", tmp[a].name, tmp[a].surname, tmp[a].age, tmp[a].wage);
}
fflush(database); fclose(database); remove("database.txt");
fflush(sorted); fclose(sorted); rename("sorted.txt", "database.txt");
}
Off by 1
Code attempts to read into len+1 elements of tmp[].
data tmp[len];
for (i=0; i<=len; i++) { // too many
fscanf(database, "%s %s %d %lf \n", &tmp[i].name, &tmp[i].surname, &tmp[i].age, &tmp[i].wage);
}
I saw that no values are assigned to the strings (OP)
Better code would use width limits and test fscanf() result before using the data scanned.
// v---- < not <=
for (i=0; i<len; i++) {
if (fscanf(database, "%63s %63s %d %lf",
&tmp[i].name, &tmp[i].surname, &tmp[i].age, &tmp[i].wage) != 4) {
// ^^^^ test!
break;
}
Even better code would read a line with fgets() into a stirng and then attempt to parse the string.
Off by 2
Code's attempt to find number of lines can be short by 1 if the last line does not end with a '\n'.
Alternative
size_t fullcheck(void) {
FILE* database = fopen("database.txt", "r");
if (database == NULL) {
return 0;
}
int previous = '\n';
int c;
size_t r=0;
while((c=getc(database))!=EOF) {
if (previous == '\n') r++;
previous = c;
}
fclose(database);
return r;
}
Missing fclose()
fullcheck() doesn't close the file after opening it.
int
Use an int to distinguish the typically 257 different returns values of fgetc(). Note when char` is unsinged, OP's code is an infinite loop.
More woes
The loop to print the sorted list is off-by-one, too short. And the sorting itself only looks at the first letter of each name, should use strcmp.
#user3386109
Maybe more?
Make sure to close the file here, before every return:
int fullcheck() {
char c;
int r=0;
FILE* database;
if ((database=fopen("database.txt", "r"))==NULL) {
fclose(database);
return 0;
}
else {
while((c=getc(database))!=EOF) {
if(c=='\n')
r++;
}
fclose(database);
return r;
}
}
And also a little bit fixing in the loop_counters here:
void sort() {
char tmpstr[MAX];
int len=fullcheck(), i, a, b;
data tmp[len];
FILE* database;
FILE* sorted;
database=fopen("database.txt", "r");
sorted=fopen("sorted.txt", "w+");
for (i=0; i<len; i++) {
fscanf(database, "%s %s %d %lf \n", &tmp[i].name, &tmp[i].surname, &tmp[i].age, &tmp[i].wage);
printf("%s", tmp[b+1].surname);
system("pause");
}
for (a=0 ; a<(len); a++) {
for (b=0; b<(len); b++) {
if ((tolower(tmp[b].surname[0]))>(tolower(tmp[b+1].surname[0]))) {
strcpy(tmpstr, tmp[b].surname);
strcpy(tmp[b].surname, tmp[b+1].surname);
strcpy(tmp[b+1].surname, tmpstr);
printf("%s", tmp[b+1].surname);
system("pause");
}
}
}
for (a=0; a<(len); a++) {
fprintf(sorted, "%s %s %d %.0lf \n", tmp[a].name, tmp[a].surname, tmp[a].age, tmp[a].wage);
}
fclose(sorted);
fclose(database);
}
New C coder here. I'm not certain why, but my program gets stuck in the first while loop and will not move on to the other code. Does anyone have any idea what's wrong?
#include <stdio.h>
int main(void){
char str[20];
char reverse[20];
int c;
int i;
int j;
int k;
printf("Enter a string: ");
i=0;
j=0;
while((i<20)&&((c=getchar())!='\n')){
str[i] = c;
i++;
}
k=i;
while((j<k)&&(i>=0)){
reverse[j]=str[i];
j++;
i--;
}
printf("\n");
if(i==0){
while(i<k){
putchar(reverse[i]);
}
}else{
printf("logic error");
}
return 0;
}
Thank you!
#include<stdio.h>
void reverse(void)
{
char c;
if((c = getchar()) != '\n'){ reverse(); }
putchar(c);
return;
}
int main(void)
{
printf("Enter a line of text below:n");
reverse();
putchar('\n');
}
Your code don't get stuck in the first while. It gets stuck here:
while(i<k){
putchar(reverse[i]);
}
because you never change i or k, i.e. an endless loop.
Try this instead:
while(i<k){
putchar(reverse[i]);
++i;
}
Another problem is that you reverse one character past the input as i has been incremented to index the "next free char" . Don't do that.
Instead of:
while((j<k)&&(i>=0)){
reverse[j]=str[i];
j++;
i--;
}
try:
while(i>=0){
reverse[j]=str[i-1]; // Notice the -1
j++;
i--;
}
++i;
Putting it all together, it will be:
int main(void){
char str[20];
char reverse[20];
int c;
int i;
int j = 0;
int k;
printf("Enter a string: ");
i=0;
j=0;
while((i<20)&&((c=getchar())!='\n')){
str[i] = c;
i++;
}
k=i;
while(i >= 0){
reverse[j]=str[i-1]; // Notice
j++;
i--;
}
++i; // Notice
printf("\n");
if(i==0){ // This if-statement is nor really needed - just remove it
while(i<k){
putchar(reverse[i]);
i++; // Notice
}
}else{
printf("logic error");
}
printf("\n");
return 0;
}
First of all, i don't know if the word alignment is the correct one to describe what i want help for so that's why i provide images from the console application.
I want to know if there is a way to make the zeros be in order . I am providing to you my code .
#include <stdio.h>
#include <stdlib.h>
int emptynes(int table1[16],int table2[16],int zero[32])
{
int i,k=1;
for(i=0;i<16;i++)
{
table1[i]=k;
k++;
}
k=17;
for(i=0;i<16;i++)
{
table2[i]=k;
k++;
}
for(i=0;i<32;i++)
zero[i]=0;
return table1,table2,zero;
}
int firstloop(int table1[16])
{
int i;
for(i=0;i<16;i++)
{
if(i==8)
printf("\n\n");
printf("%d ",table1[i]);
if(i<9)
printf(" ");
else
printf(" ");
}
}
int zeroloop(int zero[16])
{
int i;
for(i=0;i<32;i++)
{
if(i%8==0)
printf("\n\n");
printf("%d ",zero[i]);
}
}
int secondloop(int table2[16])
{
int i;
for(i=0;i<16;i++)
{
if(i==8)
printf("\n\n");
printf("%d ",table2[i]);
if(i<9)
printf("");
}
}
int twomoves(int x,int table1[16],int zero[32])
{
int i,p=0,l=0;
for(i=0;i<16;i++)
{
if(x==table1[i])
{
p=i;
break;
}
}
if(i>8)
l=table1[i]-8;
if(zero[l]==0&&zero[l+8]==0)
{
zero[l+7]=table1[i];
table1[i]=0;
}
return zero,table1;
}
int main()
{
printf("\n\n\n");
int table1[16],table2[16],zero[32];
int i,x,y,p;
emptynes(table1,table2,zero);
firstloop(table1);
zeroloop(zero);
printf("\n\n");
secondloop(table2);
printf("\n\n\n");
printf("Player 1: Pawn & Moves -> ");
scanf("%d %d",&x,&y);
twomoves(x,table1,zero); // do it as loop
firstloop(table1);
zeroloop(zero);
printf("\n\n");
secondloop(table2);
return 0;
}
Use a width specifier:
// Use (at least) 2 chars.
printf("%2d ", table1[i]);
// Use (at least) 2 chars. The minus means left adjustment.
printf("%-2d ", table1[i]);
// Use (at least) 2 chars, zero-padded.
printf("%02d ", table1[i]);
Output:
7
7
07
I keep getting these errors. Im trying to make a mine sweeper like game.
well.c: In function 'main':
well.c:170: warning: passing argument 1 of 'bombCheck' makes pointer from integer without a cast
well.c:170: warning: passing argument 3 of 'bombCheck' makes integer from pointer without a cast
well.c: In function 'fillGameBoard':
well.c:196: error: expected declaration or statement at end of input
#include <stdio.h>
#include <stdlib.h>
#define Rows 5
#define Columns 5
#define Bombs 5
void introduction(void)
{
puts("Welcome to the minefield!");
puts("In this level 2 game, you will win by choosing.");
puts("all of the viable wells and not any of the.");
puts("tool breaker spaces. In both games, there are.");
puts("20 viable spaces and 5 tool breakers!");
puts("Have fun and good luck!");
}
void fillGameBoard(char gameBoard[][Columns])
{
int i, j;
FILE *inputFile;
char gameDataFileName[30];
int yes = 0;
do
{
printf("choose your spot");
printf("\nfield1 field2\n");
scanf(" %s",&gameDataFileName);
if ((inputFile = fopen(gameDataFileName,"r")) == NULL)
{
puts("\nWrong input! Try again!");
puts("check spelling, spacing, etc. make it exact!");
}
else
{
yes = 1;
}
} while (yes == 0);
for (i=0; i<Rows; i++)
{
for (j=0; j<Columns; j++)
{
fscanf(inputFile, " %c", &gameBoard[i][j]);
}
fclose(inputFile);
return;
}
void fillUserBoard(char userBoard[][Columns])
{
int i,j; // counters
for (i=0; i<Rows; i++)
{
for (j=0; j<Columns; j++)
{
userBoard[i][j] = '~';
}
}
return;
}
void displayBoard(char board[][Columns])
{
int i, j;
printf("\n ");
for (i = 1; i <= Rows; i++)
{
printf("%d ",i+5);
}
puts("");
for (i = 0; i <=Rows; i++)
{
printf("__");
}
puts("");
for (i=0; i<Rows; i++)
{
printf("%d|",(i+1));
for (j=0; j<Columns; j++)
{
printf(" %c", board[i][j]);
}
puts("");
}
return;
}
char bombCheck (char board[][Columns], int a, int b)
{
char gameOver;
if (board[a][b] == '*')
{
puts("");
puts(" BOOM");
puts("You hit a mine.");
puts("you are deaded.\n");
puts(" GAME OVER!!\n");
gameOver = 'y';
}
else
{
gameOver = 'n';
}
return gameOver;
}
int main (void)
{
char gameBoard[Columns][Rows];
char userBoard[Columns][Rows];
char done;
char win;
char gameOver;
int count;
int i;
int col;
int row;
introduction();
do
{
done=win='n';
count=0;
fillGameBoard(gameBoard);
fillUserBoard(gameBoard);
displayboard(userBoard);
bombcheck();
do
{
displayBoard(userBoard);
printf("choose your column, numbered 1-5\n");
scanf(" %i", &col);
printf("choose your row, numbered 1-5\n");
scanf(" %i", &row);
done = bombCheck(col, row, gameBoard);
if (done='n')
{
count+1;
if (count==((Columns*Rows)-Bombs))
{
printf("you win!\n");
done='y';
}
else
{
done='n';
userBoard[col][row]=gameBoard[col][row];
}
}
} while (done != 'y');
printf("do you want to play again? y/n \n");
scanf(" %c", win);
}while (win != 'y');
return 0;
}
You're missing a brace in fillGameBoard().
for (i=0; i<Rows; i++)
{
for (j=0; j<Columns; j++)
{
fscanf(inputFile, " %c", &gameBoard[i][j]);
} /* Note closing brace! */
}
fclose(inputFile);
You're passing the arguments to bombCheck() in the wrong order.
/* Declared: char bombCheck (char board[][Columns], int a, int b) */
done = bombCheck(gameBoard, col, row);
What's with the bombcheck() call with no arguments? Note that bombcheck() is different from bombCheck(). The C programming language is case-sensitive.
For future reference, post only the minimal code snippets relevant to your question, instead of an entire program.
Case matters in C. bombcheck is not the same as bombCheck.
Argument order matters. You have declared bombCheck with (board, a, b) but are calling it with (col, row, board).
Taking the address of an array is redundant. The & is not necessary in scanf("%s",gameDataFileName);
scanf with %s is pretty unsafe. Watch what happens if you type in more than 30 characters (perhaps substantially more). Try fgets instead.
You're missing a closing brace in fillGameBoard (probably in the second inner for loop).
Your indenting is inconsistent in some places, particularly where you have left aligned return statements (and some other statements at the end of blocks).
Overall, this is a pretty good beginner program. Keep at it, and you'll get familiar with those compiler errors in no time!
There is a missing closing brace } to end the fillGameBoard function.
The number of opening and closing braces don't add up.
line 170: wrong order of arguments
line 51: missing }