I'm having problems using a fscanf function. It never reads it correctly and always results in blanks.
fscanf(f, " %[^;];%[^;];%d;%d;%d;%d;%[^;];%d;%[^\n]",
arr[i].loc1, arr[i].loc2, &arr[i].price, &arr[i].rooms,
&arr[i].bathroom, &arr[i].carpark, arr[i].type, &arr[i].area, arr[i].furnish);
The code above always outputs " 0 0 0 0 0". But when I try using a scanf and manually input one of the lines, it works perfectly.
The file it's reading from is a .csv file. Here is the contents:
Mont-Kiara;Kuala-Lumpur;1000000;2;2;0;Built-up;1000;Partly
Cheras;Kuala-Lumpur;310000;3;2;0;Built-up;1000;Partly
Kepong;Kuala-Lumpur;358000;3;3;0;Built-up;1000;Partly
Taman-Desa;Kuala-Lumpur;455000;2;2;0;Built-up;1000;Partly
Kepong;Kuala-Lumpur;358000;3;3;0;Built-up;1000;Partly
Kepong;Kuala-Lumpur;358000;3;3;0;Built-up;1000;Partly
And here is the full code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct houseData {
char loc1[101];
char loc2[101];
int price[101];
int rooms[101];
int bathroom[101];
int carpark[101];
char type[101];
int area[101];
char furnish[101];
} arr[1001];
int read() {
int i = 0;
struct houseData arr[800];
char temp1[100];
FILE *f = fopen("file.csv", "r");
while(!feof(f)){
fscanf(f, " %[^;];%[^;];%d;%d;%d;%d;%[^;];%d;%[^\n]"
, &arr[i].loc1, &arr[i].loc2, &arr[i].price, &arr[i].rooms,
&arr[i].bathroom, &arr[i].carpark, &arr[i].type, &arr[i].area, &arr[i].furnish);
i++;
}
fclose(f);
}
int main() {
read();
printf("%s %s %d %d %d %d %s %d %s", arr[i].loc1, arr[i].loc2, *arr[i].price, *arr[i].rooms, *arr[i].bathroom, *arr[i].carpark, arr[i].type, *arr[i].area, arr[i].furnish);
return 0;
}
There are a lot of issues in your code. Here's a version that may help. The error messages in this version are far from ideal (this does not distinguish between an input format error and a error reading data, for example, nor does it provide much detail on the location of the error), and there is still the possibility of undefined behavior on certain inputs, (see Is `scanf("%d", ...)` as bad as `gets`?) but this should point you in the right direction. Well, at least it may help to improve your use of scanf, but a very reasonable argument can the be made that the "right direction" is to stop using scanf completely. It is very difficult to get things right with scanf, and attempting to do so winds up being much more complex that just using fgets. But for simple use cases it is ... still pointless to use scanf. See http://sekrit.de/webdocs/c/beginners-guide-away-from-scanf.html and many other resources that explain why scanf is a terrible choice.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct houseData{
char loc1[101];
char loc2[101];
int price;
int rooms;
int bathroom;
int carpark;
char type[101];
int area;
char furnish[101];
};
int
read(FILE * f, struct houseData *h)
{
return 9 == fscanf(f, " %100[^;]; %100[^;]; %d; %d; %d; %d; "
"%100[^;]; %d; %100[^\n]", h->loc1, h->loc2, &h->price,
&h->rooms, &h->bathroom, &h->carpark, h->type, &h->area,
h->furnish);
}
int
main(int argc, char **argv)
{
int rv;
FILE *f = argc > 1 ? fopen(argv[1], "r") : stdin;
if( f == NULL ){
perror(argv[1]);
return EXIT_FAILURE;
}
struct houseData h;
int i = 0;
while( read(f, &h) ){
printf("%d: %s %s %d %d %d %d %s %d %s\n", ++i,
h.loc1, h.loc2, h.price, h.rooms, h.bathroom,
h.carpark, h.type, h.area, h.furnish);
}
if( ! feof(f) ){
fprintf(stderr, "Error near line %d\n", i);
}
fclose(f);
}
Related
I'm working on a task where I need to read a long .txt file. The first line contains the number of lines the .txt file has, the rest of the lines follow the same structure, "int int int char:char".
How do I read the first line separately from the rest?
I wrote the following code:
FILE *fajl;
falj = ("musor.txt", "r");
while (!feof(fajl) && fajl > 1)
{
fscanf_s(fajl, "%d %d %d %[^:]c:%c\n", &tomb[i].ado, &tomb[i].perc, &tomb[i].masodperc, &tomb[i].eloado, &tomb[i].cim);
i++;
}
Sorry for the unknown words, the variable names are in Hungarian.
So this is basically just the collection of all the comments from the question.
//-------------------------
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct Tomb
{
int masodperc, eloado, ado, perc;
char cim;
};
typedef struct Tomb Tomb;
//-------------------------
int main(int argc, char *argv[])
{
char linesLength[10], stringFajl[100];
FILE *fajl;
fajl = fopen("musor.txt", "r");
if(fgets(linesLength, 100, fajl)==NULL || fajl == NULL) //first line read
{
printf("error\n");
return -1;
}
int length = atoi(linesLength), i=1;
Tomb tomb[length];
while (fgets(stringFajl, 100 ,fajl )!=NULL || i<=length)
{
sscanf(stringFajl, "%d %d %d %d [^:]c:%c", &tomb[i].ado, &tomb[i].perc, &tomb[i].masodperc, &tomb[i].eloado, tomb[i].cim);
i++;
}
fclose(fajl);
return 0;
}
I have a problem, I was trying to make a C program taht read a file with 50 lines and 11 columns, the problem is that this file is completely made of strings and I made this:
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
typedef struct
{
char nome[100];
char dica[10][300];
} PAIS;
void main()
{
int i;
i = 0;
PAIS paises[50];
char nome[30];
FILE *arq;
arq = fopen("Dicas3.txt", "r");
//fscanf(arq,"%s", nome);
//printf("%s", nome);
while(!feof(arq))
{
fscanf(arq,"%s %s %s %s %s %s %s %s %s %s %s", paises[i].nome, paises[i].dica[0][0], paises[i].dica[1][0], paises[i].dica[2][0], paises[i].dica[3][0], paises[i].dica[4][0], paises[i].dica[5][0], paises[i].dica[6][0], paises[i].dica[7][0], paises[i].dica[8][0], paises[i].dica[9][0]);
printf("%s %s %s %s %s %s %s %s %s %s %s", paises[i].nome, paises[i].dica[0][0], paises[i].dica[1][0], paises[i].dica[2][0], paises[i].dica[3][0], paises[i].dica[4][0], paises[i].dica[5][0], paises[i].dica[6][0], paises[i].dica[7][0], paises[i].dica[8][0], paises[i].dica[9][0]);
i++;
}
system ("PAUSE");
}
The program compile, but the program dosn´t work. Please, could someone show me how to do a program that read a matrix 50x11 and print in the window this matrix?
the matrix is in this file (is in portuguese, but this matrix is made os strings):
https://drive.google.com/file/d/1BLhGSHIx69Ycrasgtl4lKyxxKPRlSAv2/view?usp=sharing
Dont't use feof() find out reason for Why is “while ( !feof (file) )” always wrong?
If you know well in advance about no of lines and columns, since in each line 11 columns/strings are there, read line by line from file using fgets() instead of fscanf(). My suggestion is instead of local array use dynamic array if you want to make it generic solution..
What nome[] contains, not clear ?
using fscanf() :
typedef struct
{
char nome[100];
char dica[10][300];
} PAIS;
int main()
{
PAIS paises[50];
char nome[30];
FILE *arq;
arq = fopen("Dicas3.txt", "r");
if(arq == 0) {
printf("file not present:\n");
return 0;
}
int i=0,j=0;
char ch;
while(fscanf(arq,"%s",paises[i].dica[j])>0) {
printf("%s ",paises[i].dica[j]);
j++;//column
if((ch = fgetc(arq))=='\n')//when new lines occures, start reading from next lines, do i++
{
i++;//rows or lines
printf("\n");//manuaally put the new line or use fputc(ch,stdout)
fseek(arq, -1, 1);//move one letter back
j=0;
}
else
fseek(arq, -1, 1);//move to exact position
}
return 0;
}
I hope it helps.
I'm writing a c program to simulate FCFS scheduling algorithm. It will accept a command line argument as a file and calculate turnaround time and wait time for every process. However it can not read values from text file into variables successfully.
Here is the code
#include <stdio.h>
#define N 50
int main(int argc, char** argv)
{
int i = 0;
char line[20];
int n=0;
typedef struct
{
char name; //process name
int at; //arrive time
int pt; //process time
int ft; //finish time
int rt; //round time
int wt; //wait time
} Process;
Process pcs[N];
FILE* file = fopen( argv[1], "r");
while (fgets(line,sizeof(line),file) != NULL)
{
sscanf(line, "%s %d %d", pcs[i].name, pcs[i].at, pcs[i].pt);
line[strlen(line)-1] = '\0';
printf("%s %d %d\n",pcs[i].name, pcs[i].at, pcs[i].pt);
i++;
}
fclose(file);
pcs[0].ft=pcs[0].at+pcs[0].pt;
pcs[0].rt=pcs[0].ft-pcs[0].at;
pcs[0].wt=0;
for (n;n<4;n++)
{
if (pcs[n].at<pcs[n-1].ft)
{
pcs[n].ft=pcs[n-1].ft+pcs[n].pt;
pcs[n].rt=pcs[n].ft-pcs[n].at;
pcs[n].wt=pcs[n-1].ft-pcs[n].at;
}
else
{
pcs[n].ft=pcs[n].at+pcs[n].pt;
pcs[n].rt=pcs[n].ft-pcs[n].at;
pcs[n].wt=pcs[n-1].ft-pcs[n].at;
}
}
int x = 0;
for (x;x<n;x++)
{
printf("process name: %s", pcs[x].name);
printf("Turnaround Time: %d", pcs[x].rt);
printf("Wait Time: %d\n", pcs[x].wt);
}
return(0);
}
Here is the input file
And the output is
Thanks for any help and advice.
As pointed by alk, you're doing some mistakes:
In your struct declaration you have declared name as a single character, but in your file reading code(while loop containing fgets) you're passing %s which is for strings, so better change your declaration to a char name[SIZE] rather than char name. Bdw you should read the compiler warning and try to understand it, since that's what is creating problem.
You are supposed to pass address of variables in sscanf and it's variants, so change line 26 to:
sscanf(line, "%s %d %d", pcs[i].name, &pcs[i].at, &pcs[i].pt);
I am trying to write a program in C that reads from an input file ("input0") which follows the format:
John Doe 1230 4.0
I am trying to read from the document using fscanf and enter those values into a struct. Currently, though, after compiling and once I run my code, I run into the enigmatic "Segmentation Fault (Core Dumped)."
The line in my code currently giving off this error the line with fscanf statement. I can't find the solution to this.
Additionally, strcpy gives an error once its uncommented. I get a warning when I run the code, which I believe has to be with a discrepancy with what is a pointer and what's the string, another problem I can't fix. Any help would be appreciated.
typedef struct {
char fname[1000];
char lname[1000];
long int id;
double gpa;
} student_t;
int main(int argc, char *argv[]) {
FILE *db;
student_t students[1000];
char* fname[1000];
char* lname[1000];
long int id[1000];
double gpa[1000];
long int i, j;
i = 0;
db = fopen("input0", "r");
while(fscanf(db, "%s %s %d %lf", fname[i], lname[i], id[i], gpa[i]) != EOF) {
//strcpy(students[i].fname, fname[i]);
//strcpy(students[i].lname, lname[i]);
students[i].id = id[i];
students[i].gpa = gpa[i];
i++;
}
for(j = 0; j <= i; j++) {
//printf("%s %s %d %f\n", _SJ.fname, _SJ.lname, _SJ.id, _ST.gpa);
}
fclose(db);
}
When you declare e.g.
char* fname[1000];
you have an array of 1000 uninitialized pointers. Trying to use one of those pointers will lead to undefined behavior. You need to either allocate memory for the pointers, or point them to some other (already allocated) memory.
Actually, I think what you really meant to do is
fscanf(db, "%s %s %d %lf",
students[i].fname, students[i].lname, &students[i].id, &students[i].gpa)
I also suggest you read e.g. this fscanf reference, as fscanf can return other values that means there are errors in the input (for example if the input file is malformed).
You forgot to use & for long int and double in fscanf
while(fscanf(db, "%s %s %d %lf", fname[i], lname[i], &id[i], &gpa[i]) != EOF)
Change this line
while(fscanf(db, "%s %s %d %lf", fname[i], lname[i], id[i], gpa[i]) != EOF)
to
while(fscanf(db, "%s %s %d %lf", students[i].fname, students[i].lname, &students[i].id, &students[i].gpa) != EOF)
Then probably you do not need any strcpy or copy back int and double to the stucture.
char *fname[1000] will allocate 1000 pointers of char
I fixed some problems:
typedef struct {
char fname[1000];
char lname[1000];
long int id;
double gpa;
} student_t;
student_t students[1000];
int main(int argc, char *argv[]) {
FILE *db;
long int i=0, j;
db = fopen("input0.txt", "r");
if (db == NULL)
{
perror("Error opening file input0");
return -1;
}
while (fscanf(db, "%s %s %d %lf", students[i].fname, students[i].lname,
&students[i].id, &students[i].gpa) != EOF)
{
i++;
}
for (j = 0; j < i; j++) {
printf("%s %s %d %f\n", students[j].fname, students[j].lname, students[j].id, students[j].gpa);
}
fclose(db);
}
You can read directly to the students array, avoiding having to play with strcpy. The missing & were added too.
Please note that I moved students[1000] outside the main function, as with the standard stack size of VS2013 the code generated a stack overflow. When opening file, always check if you managed to open them... this will save many hours of debug pain in the future. The j<=i condition was changed to j
In your original code:
char* fname[1000];
You used 1000 char*, but this line only allocates the space for the pointers itself. I think you were trying to write something like:
char fname[1000];
In this case, frame would have 1000 chars you could use to store the name read from the input file. It is very important to note the diference between these two lines before going further studying C. In the case of fname[1000], you could read to fname, i.e., no indexes. Then strcpy(students[i].fname, fname). I hope it helps.
New question: I have to read in data from files into an array of structures, and I'm getting errors with my scanf function. I'm really unsure of the details of scanning into structures. This is what I have written:
#include <stdio.h>
#include <string.h>
#include <math.h>
#define runnum 500
#define charnum 20
typedef struct {
unsigned long bibnum;
char lastname[charnum];
char fistname[charnum];
int grade;
char team[charnum];
char state[charnum];
int time1;
float time2;
} runner_t;
int main(void)
{
int i;
FILE *ifile, *jfile;
ifile = fopen("20121006.boys.txt", "r");
jfile = fopen("20121006.girls.txt", "r");
runner_t runarray[runnum];
i = 0;
while (i < runnum)
{
scanf(ifile, "%ul", &runarray[i].bibnum);
scanf(ifile, "%s", &runarray[i].lastname);
scanf(ifile, "%s", &runarray[i].firstname);
scanf(ifile, "%d", &runarray[i].grade);
scanf(ifile, "%s", &runarray[i].team);
scanf(ifile, "%s", &runarray[i].state);
scanf(ifile, "%d", &runarray[i].time1);
scanf(ifile, "%f", &runarray[i].time2);
printf("%d %s %s %d %s %s %d:%f", runarray[i].bibnum, runarray[i].lastname, runarray[i].firstname, runarray[i].grade, runarray[i].team, runarray[i].state, runarray[i].time1, runarray[i].time2);
i++;
}
#include <stdio.h>
#include <string.h>
#include <math.h>
#define RUNNUM 500
#define CHARNUM 20
typedef struct {
unsigned long bibnum;
char lastname[CHARNUM];
char firstname[CHARNUM];
int grade;
char team[CHARNUM];
char state[CHARNUM];
int time1;
float time2;
} runner_t;
int main(void)
{
int i;
FILE *ifile, *jfile;
ifile = fopen("20121006.boys.txt", "r");
jfile = fopen("20121006.girls.txt", "r");
runner_t runarray[RUNNUM];
for (i=0; i < RUNNUM; i++)
{
fscanf(ifile, "%lu", &runarray[i].bibnum);
fscanf(ifile, "%s", runarray[i].lastname);
fscanf(ifile, "%s", runarray[i].firstname);
fscanf(ifile, "%d", &runarray[i].grade);
fscanf(ifile, "%s", runarray[i].team);
fscanf(ifile, "%s", runarray[i].state);
fscanf(ifile, "%d", &runarray[i].time1);
fscanf(ifile, "%f", &runarray[i].time2);
printf("%lu %s %s %d %s %s %d:%f"
, runarray[i].bibnum
, runarray[i].lastname, runarray[i].firstname
, runarray[i].grade, runarray[i].team
, runarray[i].state
, runarray[i].time1, runarray[i].time2);
}
return 0;
}
Compiles here.
Your struct code is fine, see this if you don't believe it otherwise. That ideone.com snippet adds just this main function, and works fine:
int main(void) {
runner_t foo;
printf ("sizeof foo is %zu\n", sizeof foo);
return 0;
}
See http://sscce.org for good advice on how to avoid getting downvotes for badly asked question...
After edit: use fscanf, because scanf does not take FILE* as first argument (check documentation for both). Always check return value of any scanf family
function. Also check return value of fopen for errors.
Additionally, do not use & when passing array for fscanf %s. Name of array means address of array, and taking & of that makes no sense, and is not allowed. So for example: fscanf(ifile, "%s", runarray[i].state);
The editor problem is purely cosmetic. You can try this instead:
typedef struct runner_t {
// ...
} runner_t;
Note though that the _t suffix is reserved on POSIX systems (like Mac OS X and Linux). It's better to either use _type instead, or no suffix at all.
Your problems though (the compilation errors) lie elswhere. First, you're using scanf() instead of fscanf(). scanf() always reads from the stdin stream and has no FILE* argument (so the compiler sees it as an error when you try to pass a FILE* as the first argument, since it always expects a const char* instead.) To read from your own file streams, you need to use fscanf(), which does take a FILE* argument. E.g.:
fscanf(ifile, "%lu", &runarray[i].bibnum);
Note: it's %lu, not %ul.)
Also note that when you read in the strings, you're passing pointers to them even though they're already pointers:
fscanf(ifile, "%s", &runarray[i].lastname);
Since runner_t.lastname is already a pointer, just pass it as-is:
fscanf(ifile, "%s", runarray[i].lastname);
Furthermore, you misspelled runner_t.firstname in the struct declaration. You named it fistname. Change that too.
Finally, in your printf(), you use %d as the format specifier to print bignum. Since it's an unsigned long, you need to use %lu.