Reading data from a file into a structure array (C) - c

I'm trying to build a simple function that will take in a data file, and assign various values from the data file into a global array of structures. However, I'm having trouble getting it to work quite right. I've written what I believe is most of the needed code, but my test line printf("time is %d\n", BP[i].time); simply reads out "Time is 0." 10 times, leading me to believe the values aren't getting assigned to the structure array like I imagined they would be.
How can I proceed further?
Example Data File (.txt):
0001 553 200
0002 552 100
.... ... ...
Current Code:
#include <stdio.h>
#include <stdlib.h>
// Function Prototype
void readFileBP(char fileName[1000]);
// Definition of BP Structure
struct bloodPressure
{
int *time;
int *sys;
int *dia;
}BP[50]; // end struct BP
int main()
{
char fileName[1000] = "C:\\Users\\User\\Desktop\\DataFiles\\BP_1.txt";
readFileBP(fileName);
int i = 0;
for (i; i<10; i++)
{
printf("Time is %d\n", BP[i].time);
}
} // end int main()
void readFileBP(char fileName[1000])
{
FILE *filePtr; // declare file pointer
int time;
int sys;
int dia;
int position = 0;
if (filePtr = fopen(fileName, "r") == NULL) // error check opening file
{
printf("Opening file failed. Please reenter filename.");
exit(1);
} // end if
while (fscanf(filePtr, "%d, %d, %d", &time, &sys, &dia) != EOF) // read in BP values
{
BP[position].time = time;
BP[position].sys = sys;
BP[position].dia = dia;
position++;
} // end while
fclose(filePtr);
} // end void readFile()

Compile with warnings enabled. You should get something like that:
gsamaras#gsamaras-A15:~$ gcc -Wall -o px px.c
px.c: In function ‘main’:
px.c:22:5: warning: statement with no effect [-Wunused-value]
for (i; i<10; i++)
^
px.c:24:9: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘int *’ [-Wformat=]
printf("Time is %d\n", BP[i].time);
^
px.c: In function ‘readFileBP’:
px.c:37:17: warning: assignment makes pointer from integer without a cast [enabled by default]
if (filePtr = fopen(fileName, "r") == NULL) // error check opening file
^
px.c:37:5: warning: suggest parentheses around assignment used as truth value [-Wparentheses]
if (filePtr = fopen(fileName, "r") == NULL) // error check opening file
^
px.c:45:27: warning: assignment makes pointer from integer without a cast [enabled by default]
BP[position].time = time;
^
px.c:46:26: warning: assignment makes pointer from integer without a cast [enabled by default]
BP[position].sys = sys;
^
px.c:47:26: warning: assignment makes pointer from integer without a cast [enabled by default]
BP[position].dia = dia;
^
px.c: In function ‘main’:
px.c:26:1: warning: control reaches end of non-void function [-Wreturn-type]
} // end int main()
^
Isn't that enough to get you started? It was for me! :)

I made some changes and ran it just now.
#include <stdio.h>
#include <stdlib.h>
// Function Prototype
void readFileBP(char fileName[1000]);
// Definition of BP Structure
struct bloodPressure
{
int time;
int sys;
int dia;
}; // end struct BP
struct bloodPressure BP[50];
int main()
{
char *fileName = "file.txt";
readFileBP(fileName);
int i = 0;
for (i; i<10; i++)
{
printf("Time is %d\n", BP[i].time);
}
getch();
}
void readFileBP(char fileName[1000])
{
FILE *filePtr; // declare file pointer
int time=0;
int sys=0;
int dia=0;
int position = 0;
filePtr= fopen(fileName,"r");
while (fscanf(filePtr, "%d, %d, %d", &time, &sys, &dia) != EOF) // read in BP values
{
BP[position].time = time;
BP[position].sys = sys;
BP[position].dia = dia;
position++;
} // end while
fclose(filePtr);
} // end void readFile()
The output is now:
Time is 1
Time is 553
Time is 200
Time is 2
Time is 552
Time is 100
Time is 0
Time is 0
Time is 0
Time is 0

try changing the line :
while (fscanf(filePtr, "%d, %d, %d", &time, &sys, &dia) != EOF)
to
while (fscanf(filePtr, "%d%d%d", &time, &sys, &dia) != EOF)
also here's what i tried out and it seems to work based on the tests i've done
#include <stdio.h>
#include <stdlib.h>
#define MAX_ARRAY_SIZE 50
typedef struct BloodPressure
{
int time;
int sys;
int dia;
}BloodPressure;
BloodPressure bloodPressure[MAX_ARRAY_SIZE];
void ReadFile(char *fileName);
int main(int argc, char *argv[])
{
char *fileName = "BP_1.txt";
ReadFile(fileName);
int i = 0;
for (i = 0; i < MAX_ARRAY_SIZE; i++)
{
printf("Dia is : %d\n", bloodPressure[i].dia);
printf("Sys is : %d\n", bloodPressure[i].sys);
printf("Time is : %d\n", bloodPressure[i].time);
printf("\n");
}
exit(EXIT_SUCCESS);
}
void ReadFile(char *fileName)
{
FILE *filePtr = NULL;
int i = 0;
if ((filePtr = fopen(fileName, "r")) == NULL)
{
printf("Error : Unable to open %s for reading\n");
exit(EXIT_FAILURE);
}
while (fscanf(filePtr, "%d%d%d", &bloodPressure[i].dia, &bloodPressure[i].sys, &bloodPressure[i].time) != EOF)
{
i++;
}
fclose(filePtr);
}

Related

C Pointer Error

The program below is supposed to read a txt file and put the data in a struct. But it gives an pointer error. It gives an error in strcpy() about pointers. I'm new in C. Whats wrong?
#include <stdio.h>
#include <string.h>
int main()
{
struct citydata {
char city[20];
int temp;
};
struct citydata values[15];
struct citydata Avg;
struct citydata high;
struct citydata low;
FILE* inp;
int reccount = 0;
int x = 0;
char s;
int n;
inp = fopen("mydata.txt", "r");
if (!inp) {
printf("Unable ot open file\n");
}
while (fscanf(inp, "%s %d", s, &n) != EOF) {
strcpy(values[x].city, s);
values[x].temp = n;
x++;
}
fclose(inp);
}
Don't ignore compiler warnings.
When if you compile this code (say, with gcc), you get the following warnings:
test.c:27:24: warning: format ‘%s’ expects argument of type ‘char *’, but argument 3 has type ‘int’ [-Wformat=]
while (fscanf(inp, "%s %d", s, &n) != EOF) {
^
test.c:28:32: warning: passing argument 2 of ‘strcpy’ makes pointer from integer without a cast [-Wint-conversion]
strcpy(values[x].city, s);
^
In file included from test.c:2:0:
/usr/include/string.h:125:14: note: expected ‘const char * restrict’ but argument is of type ‘char’
extern char *strcpy (char *__restrict __dest, const char *__restrict __src)
so, as comments suggest, you can't scan directly into the struct; you can only scan into simpler types the C standard libraries recognizes: integer, floating-point numbers, char * strings etc. Similarly, you can't perform a string copy from your structs, which are not strings.
C is a strongly-typed language with very few allowed implicit conversions. In some cases, you are able to pass integers instead of floats or vice-versa, but nothing "magically converts" into a string, or is "magically parsed" from a string.
... and there are other issues:
Note #EdHeal 's comment: If your fopen() fails, you mustn't continue running the rest of the code. Either you should exit(EXIT_FAILURE); or wrap the rest of the code in main() within an else() block.
You should printf error messages to the standard error stream, so instead of printf("error message here") it should fprintf(stderr,"error message here"). Also, the standard C library places an error code you can get as the errno variable, or you can have an error message printed to the standard error stream with the perror() function. There are a few other related related functions (like strerror(), `err() etc.) which I will not get into here.
make some mistakes with pointers=)
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct citydata
{
char *city;
int temp;
} citydata;
int main()
{
char *s;
citydata *values;
values = (citydata*)malloc(sizeof(citydata) * 16);
FILE * inp;
int reccount = 0;
int x = 0;
int n;
inp = fopen("mydata.txt", "r");
if(!inp)
printf("Unable ot open file\n");
while (fscanf(inp,"%s %d",s, &n) != EOF)
{
values[x].city = (char*)malloc(sizeof(char) * 20);
strcpy(values[x].city, s);
values[x].temp = n;
x++;
}
fclose(inp);
}

passing argument 1 of âgetGradesFromFileâ makes integer from pointer without a cast

I am writing a program to read a file of records, extract some fields into a VLA’s, sort them using insertion sort, search for a user-specified target using binary search, and print out the result.
Bud I keep getting these errors:
search.c: In function âmainâ:
search.c:57: warning: passing argument 1 of âgetGradesFromFileâ makes integer from pointer without a cast
search.c:19: note: expected âintâ but argument is of type âchar *â
search.c:57: warning: passing argument 2 of âgetGradesFromFileâ makes pointer from integer without a cast
search.c:19: note: expected âchar *â but argument is of type âintâ
search.c:57: warning: passing argument 3 of âgetGradesFromFileâ from incompatible pointer type
search.c:19: note: expected âint *â but argument is of type âchar *â
search.c:57: warning: passing argument 4 of âgetGradesFromFileâ makes integer from pointer without a cast
search.c:19: note: expected âintâ but argument is of type âint *â
search.c:57: warning: passing argument 7 of âgetGradesFromFileâ makes pointer from integer without a cast
search.c:19: note: expected âchar *â but argument is of type âintâ
search.c:57: error: too many arguments to function âgetGradesFromFileâ
search.c:59: warning: passing argument 1 of âprintArrayâ makes integer from pointer without a cast
search.c:38: note: expected âintâ but argument is of type âchar *â
search.c:59: warning: passing argument 2 of âprintArrayâ makes pointer from integer without a cast
search.c:38: note: expected âchar *â but argument is of type âintâ
search.c:62: error: expected expression before âintâ
search.c:62: error: too few arguments to function âinsertionSortâ
search.c:67: warning: comparison between pointer and integer
search.c:68: warning: comparison between pointer and integer
search.c:68: warning: comparison between pointer and integer
search.c:69: warning: passing argument 3 of âbinarySearchâ makes integer from pointer without a cast
search.c:33: note: expected âintâ but argument is of type âint (*)[60]â
search.c:69: error: too few arguments to function âbinarySearchâ
search.c:73: error: expected â(â before â{â token
Any help with these errors is appreciated!!
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
void getGradesFromFile(int size,
char line[],
int studentI_D[],
int test1,
int test2,
int test3,
char grades[]);
void insertionSort(char list[],
int last);
void binarySearch(int size,
int studentID[],
int target,
char* locn);
void printArray(int size,
char list[*],
int studentI_D[*],
int test1,
int test2,
int test3,
char grades[*]);
int main(void)
{
char grades[60];
char str[60];
int size = sizeof(str) / sizeof(str[60]);;
int studentID [60];
char letter;
int exam1, exam2, exam3;
getGradesFromFile("grades.csv", size, str, studentID, exam1, exam2, exam3, grades);// function call
printf("The original numbers are:");
printArray(str, size, studentID, exam1, exam2, exam3, grades);
printf("\n\n");
printf("The sorted numbers are:");
insertionSort(int size, studentID, grades);// inscertion sort function call
printf("\n\n");
printf("Enter student ID and -1 to quit");
scanf("%d", studentID);
while (studentID != -1){
if (studentID > 99999 && studentID < 1000000){
binarySearch(size, studentID, &studentID);
}
else if {
printf ("Error and enter again [100000, 999999] and -1 to quit");
}
exit;
}
return 0;
} // end of main
void getGradesFromFile(int size,
char line[],
int studentI_D[],
int test1,
int test2,
int test3,
char grades[])
{
FILE* pData;
int i = 0;
if ((pData == NULL) {// opens file grades.csv
fprintf(stderr, "Error opening file %s.\n");// error handling statement
exit(1);
}
while (fgets(line,sizeof(line), pData) != NULL){
sscanf(line, "%25s, %d, %d, %d, %c", studentID[i], &test1, &test2, &test3,
grades[i]);
i++;
}
}
if fclose(pData) {
fprintf(stderr, "Error closing file %s.\n", filename);// close file
exit(2);
}
}
void insertionSort(int length, int studentID[], char grades[])
{
int i, key, key1, j;
for (i = 1; i < n; i++)
{
key = studentID[i];
key1= grades[i];
j = i-1;
while (j >= 0 && studentID[j] > key)
{
studentID[j+1] = studentID[j];
grades[j+1] = grades[j];
j = j-1;
}
studentID[j+1] = key;
grades[i+j] = key1;
}
}
void binarySearch(int size, int student[], int target, char *locn)
{
int first = 0;
int last = size - 1;
int mid;
bool found = false;
while (first <= last) {
mid = (first + last) / 2;
if (target > list[mid]) {
first = mid + 1;
} else if (target < list[mid]) {
last = mid - 1;
} else {
*locn = mid;
found = true;
break;
}
}
return found;
}
void printArray(int size,
char A[size],
int studentI_D[size],
int test1,
int test2,
int test3,
char grades[size])
{
for (int i=0; i<size; i+=4) {// prints the array in four lines
printf("\n");
for (int j=0; j<4; j++) {
printf("%10.2f ", A[i+j]);
}
}
}
void flushScanf(void)
{
char c;
while((c = getchar() != '\n' && c != EOF)
;
}
void getGradesFromFile(int size,
char line[],
int studentI_D[],
int test1,
int test2,
int test3,
char grades[]);
size is int type but you are passing "grades.csv" which is a string hence its address will be paased and hence it becomes pointer.
line[] is an array hence a pointer, You are passing size of type int
studentI_D[] is an array of type int. you are passing str of type char and so on....
Your function declaration and definition got 7 parameters but you are passing 8 parameters and hence resulting in error.
You need to check rest yourself. These are silly errors.

bad file descriptor from fread

I try to use read() to get some characters from file just for learning this API. I have create a file called "file" in the same directory and it contains 1000 characters. But I got an error saying:
read: %m: Bad file descriptor
Here is the code:
#include <stdio.h>
#include <error.h>
int read_indent(int sockfd){
int sport, cport;
char user[2], rtype[2], addinfo[2];
char buffer[17];
if(read(sockfd, buffer, sizeof(buffer)) <= 0) {
perror("read: %m");
return -1;
}
buffer[sizeof(buffer)-1] = '\0';
sscanf(buffer, "%d:%d:%s:%s:%s", &sport, &cport, rtype, user, addinfo);
printf("%d:%d:%s:%s:%s", sport, cport, rtype, user, addinfo);
return 0;
}
int main(){
FILE *file_pt = fopen("file", "r");
if(file_pt == NULL) { printf("fopen error\n"); return -1;}
char buf[128];
int a = read_indent(file_pt);
fclose(file_pt);
return 0;
}
UPDATE 1: Compilation message
test.c: In function ‘main’:
test.c:27:2: warning: passing argument 1 of ‘read_indent’ makes integer from pointer without a cast [enabled by default]
int a = read_indent(file_pt);
^
test.c:4:5: note: expected ‘int’ but argument is of type ‘struct FILE *’
int read_indent(int sockfd){
Your read_indent function takes a file descriptor, but you're passing in a FILE* pointer. Try turning the FILE* pointer into a file descriptor using fileno:
int a = read_indent(fileno(file_pt));

Arrays and Structs

I am taking an online college course introducing C and am completely stumped on my latest project. My professor to research online for the errors but the examples don't seem to match. I started the program on Visual Studio 2013 and now have moved to Code::blocks from the professor's instruction.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
typedef struct flightRec { // declare a struct to match the format of the binary data
char FlightNum[7];
char OriginAirportCode[5];
char DestAirportCode[5];
int timestamp;
} flightRec;
int flightCmp(const void *a, const void *b) // comparison function of DestAirportCode to ascending order
{
const flightRec *p1 = (flightRec *)a;
const flightRec *p2 = (flightRec *)b;
if (p1->DestAirportCode < p2->DestAirportCode)
return -1;
else if (p1->DestAirportCode > p2->DestAirportCode)
return +1;
else
return 0;
}
int codeInst(int count, int i, char currCode, char nextCode, flightRec flightInfo[1000]) { // function that counts how many instances of each code exist
count = 0; // set count to zero
i = 0;
currCode = flightInfo[i].DestAirportCode; // get a code from the array, call it currCode
while (i < 1000 ) { // while you've not come to the end of the array
nextCode = (&flightInfo[i+1].DestAirportCode); // get the next code from the array
if (nextCode == currCode) { // if the next code equals the current code
count += 1; // then add one to count
}
else {
printf("Destination Airport Code: %s Count: %i", flightInfo->DestAirportCode, count); // else output code and count
currCode = nextCode; // set currCode to nextCode
count = 0; // set count to 0
}
++i;
}
}
int main(){
flightRec flightInfo[1000];
int i = 0;
int codeInst;
FILE* inFile = NULL;
inFile = fopen("acars.bin", "rb");
struct tm* timestamp;
if (inFile == NULL) {
printf("Could not open file acars.bin.\n");
return -1;
}
while (!feof(inFile)) {
for (i = 0; i < 1000; ++i) {
fread(&flightInfo[i], sizeof(flightInfo), 1, inFile); // read the acars.bin file into an array of these structs
}
for (i = 0; i < 1000; ++i) {
qsort(flightInfo, 1000, sizeof flightInfo, flightCmp); // sort the array
}
for (i = 0; i < 1000; ++i) {
localtime(flightInfo[i].timestamp); // Do localtime () on the timestamp member of the struct, then asctime on the time struct you get back from localtime
return timestamp;
}
int codeInst(flightInfo); // algorithm to count how many instances of each code exists
for (i = 0; i < 1000; ++i) {
printf("Flight Number: %s \nOriginal Airport: %s \nDestination Airport: %s \nDestination Airport Count:%i \nTime: %d \n\n", &flightInfo[i].FlightNum, &flightInfo[i].OriginAirportCode, &flightInfo[i].DestAirportCode, codeInst, timestamp); // print the flightRec structs in form of member columns
}
}
fclose(inFile);
system("pause");
}
Build Messages:
||=== Build: Debug in Project6 (compiler: GNU GCC Compiler) ===|
In function 'codeInst':|
|28|warning: assignment makes integer from pointer without a cast [enabled by default]|
|30|warning: assignment makes integer from pointer without a cast [enabled by default]|
||In function 'main':|
|70|warning: passing argument 1 of 'localtime' makes pointer from integer without a cast [enabled by default]|
|121|note: expected 'const time_t *' but argument is of type 'int'|
|71|warning: return makes integer from pointer without a cast [enabled by default]|
|74|error: expected declaration specifiers or '...' before 'flightInfo'|
|76|warning: format '%s' expects argument of type 'char *', but argument 2 has type 'char (*)[7]' [-Wformat]|
|76|warning: format '%s' expects argument of type 'char *', but argument 3 has type 'char (*)[5]' [-Wformat]|
|76|warning: format '%s' expects argument of type 'char *', but argument 4 has type 'char (*)[5]' [-Wformat]|
|76|warning: format '%d' expects argument of type 'int', but argument 6 has type 'struct tm *' [-Wformat]|
83|warning: control reaches end of non-void function [-Wreturn-type]|
c||In function 'codeInst':|
|43|warning: control reaches end of non-void function [-Wreturn-type]|
||=== Build failed: 1 error(s), 10 warning(s) (0 minute(s), 0 second(s)) ===|
You have initially a function called codeInst, after that, in your main function, you declared a integer variable called codeInst, in line 73 you coded a statement that I really don't know what you want to do (int codeInst(flightInfo);).I assume that you want to call the function int codeInst and for that you must:
change the name of the variable like codeInstVarible
assign to codeInstVarible the function codeInstVarible = codeInst()
and fill all existing parameters in the function in case: (int count, int i, char currCode, char nextCode, flightRec flightInfo[1000])
Check out for info:
[c function localtime()][1]
For the error: |121|note: expected 'const time_t *' but argument is of type 'int'|
In your localtime(flightInfo[i].timestamp),
flightInfo[i].timestamp is an int, not a const time_t *(a pointer to a time_t).
For your int codeInst(flightInfo); function, it should have a return type.
In your main function, you wrote
int codeInst(flightInfo);
Which is incorrect. Look at BarbarianSpock's response.

Error in using typedef

I have this code in c-
This is my Room.h file
typedef int Room[10][10];
THis is my main code-
#include"Room.h"
#include<stdio.h>
#include<stdlib.h>
int createRoom(Room * pm,char *filename)
{
FILE * input;FILE * output;
input=fopen(filename,"r");
int a;int i=0,j=0;int count;
fscanf(input,"%d",&a);
while(!feof(input))
{
pm[i][j]=a; // incompatible types when assigning to type ‘int[10]’ from type ‘int’
i++;j++;count++;
fscanf (input, "%d", &a);
}
for(i=0;i<count;i++)
{
for(j=0;j<count;j++)
printf("%d ",pm[i][j]);
printf("\n");
}
fclose(input);
return count;
}
int main()
{
char name[100];
printf("Enter file name\n");
scanf("%s",name);
Room *pm;
//pm=malloc(sizeof(Maze ));
int n=createRoom(pm,name);
return 0;
}
I get this error- incompatible types when assigning to type ‘int[10]’ from type ‘int’ in this line-pm[i][j]=a; .Why is it so?
This line
pm[i][j]=a;
needs to be changed to
(*pm)[i][j]=a;
More importantly, your code does not allocate memory for pm. In main, you have:
Room *pm;
//pm=malloc(sizeof(Maze ));
int n=createRoom(pm,name);
I wonder why you removed the line to allocate memory for pm. You can use:
Room *pm;
pm=malloc(sizeof(*pm));
int n=createRoom(pm,name);
and make sure to deallocate memory.
free(pm);
Or, you could just use:
Room pm;
int n=createRoom(&pm,name);

Resources