Reputation: 37
I am reading a data file with numbers in it and extracting some of the numbers and converting them into one integer.
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
int main(void) {
FILE* fp = fopen("data.txt", "r");
int i;
char data[5];
for(i = 0; i < 5; i++)
{
data[i] = fgetc(fp);
}
fclose(fp);
}
I have an array of dates in a char matrix and want to have separate arrays for the date month and year. How do I take any n numbers from the data file and turn them into an n digit integer? I have tried strcat followed by atoi but my lack of understanding of pointers gets in the way and I constantly get error messages?
I/O:
Input data (bank statement):
09,08,2014,"BOOK SHOP",12.34,5.67,
10,08,2014,"CAR MECHANIC",52.44,5.67,
11,08,2014,"CHIP SHOP",67.34,5.67,
The desired output is separate arrays for date, month, year, place of purchase, amount and balance. I have separate arrays for each but the numbers are strings and not integers. How can I convert each column to an integer array?
Upvotes: 2
Views: 199
Reputation: 753565
I'm assuming you are interested in reading the lines of data like:
09,08,2014,"BOOK SHOP",12.34,5.67,
10,08,2014,"CAR MECHANIC",52.44,5.67,
11,08,2014,"CHIP SHOP",67.34,5.67,
It looks like you can use fscanf()
, but you need to be careful:
int day[20];
int month[20];
int year[20];
char name[20][15];
double amount[20];
double balance[20];
for (int i = 0; i < 20; i++)
{
if (fscanf(fp, "%d ,%d ,%d , \" %14[^\"] \" ,%lf ,%lf ,",
&day[i], &month[i], &year[i], name[i],
&amount[i], &balance[i]) != 6)
break;
}
You might not need every one of the spaces, and you'll never know whether the final comma on the line was missing. Note that the code avoids buffer overflows, both by limiting the number of iterations on the loop and by limiting the length of the string field. I chose 15
for the length of the names simply so that it is clear which number is the number of entries and which is the length of each entry.
You might prefer the fgets()
and sscanf()
approach:
int day[20];
int month[20];
int year[20];
char name[20][15];
double amount[20];
double balance[20];
char buffer[4096];
int i; // Outside loop so it can be accessed after the loop
for (i = 0; i < 20 && fgets(buffer, sizeof(buffer), fp) != 0; i++)
{
if (sscanf(buffer, "%d ,%d ,%d , \" %14[^\"] \" ,%lf ,%lf ,",
&day[i], &month[i], &year[i], name[i],
&amount[i], &balance[i]) != 6)
break;
}
This will reject lines which don't match, whereas the original code using fscanf()
directly would work with data like this:
09,08,2014,"BOOK SHOP",12.34,5.67,10,08,2014,"CAR MECHANIC",
52.44,5.67,11,
08,
2014,
"CHIP SHOP",
67.34,
5.67,
The code shown more or less replaces the lines in the question from char data[5];
through the end of the loop. You can add code to print the values read.
for (int j = 0; j < i; j++)
printf("%.4d-%.2d-%.2d %-14s %8.2f %8.2f\n",
year[j], month[j], day[j], name[j], amount[j], balance[j]);
Upvotes: 1
Reputation: 2282
If you NULL
terminate your character array, then it is effectively a string representation of a number as far as C is concerned. You can then just use atoi()
directly on it:
int data_int;
char data_str[N+1];
for (i = 0; i < N; i++)
{
data_str[i] = fgetc(fp);
/* to be really sure, you should make sure each character
* you read is a decimal digit from '0' - '9'
*/
}
data_str[N] = '\0';
data_int = atoi(data_str);
Upvotes: 1