Reading both string and integer from a text file
Solution 1
If the file is in exactly that format, you can use scanf()
easily. Here's some code to get you started; I haven't tested this and you need to fill in a few missing things.
#include <ctypes.h> // for isspace()
#include <stdio.h> // for scanf(), getchar(), and EOF
char c2d[MAX_LINES][MAX_LENGTH_STRING_PER_LINE];
char *pstr;
float f2d[MAX_LINES][6]; // 6 floats per line
float *p;
int c, current_line_number;
char ch;
FILE *input;
input = fopen(...);
if (!input)
... handle the error
for (current_line_number = 0; ; ++current_line_number)
{
// handle each line of input
// first read 6 float values
p = f2d + current_line_number;
c = fscanf(input, "%f %f %f %f %f %f", p + 0, p + 1, p + 2, p + 3, p + 4, p + 5);
if (c != 6)
... handle the error here
// next grab string; stop at '<' or end of line or EOF
pstr = c2d + current_line_number;
for (;;)
{
ch = fgetc(input);
if (ch == EOF || ch == '<' || ch == '\n')
{
*pstr = '\0';
break;
}
*pstr++ = ch;
}
if (ch == '<')
{
// char was '<' so throw away rest of input line until end of line
for (;;)
{
if (ch == EOF || ch == '\n')
break;
ch = fgetc(input);
}
}
for (;;)
{
// eat up any white space, including blank lines in input file
if (ch == EOF || !isspace(ch))
break;
ch = fgetc(input);
}
// once we have hit end of file we are done; break out of loop
if (ch == EOF)
break;
}
fclose(input);
I didn't use scanf()
to read the string at the end of the line because it stops when it hits white space, and your string values have spaces in them.
If the input file isn't always six float values, you will need to write code to call scanf()
one float at a time until you hit something that doesn't parse as a float, and you will need to make the array of floats wide enough to handle the largest number of floats you will permit per line.
Good luck.
Solution 2
Instead of using fscanf
I would recommend using fgets
to get the line. Then use sscanf
on that line to get the numeric values, and search for the first alphabetic character to know where the string starts (using e.g. strspn
).
Something like this:
char line[256];
while (fgets(line, sizeof(line), fp) != NULL)
{
/* Get the numbers */
float numbers[6];
sscanf(line, "%f %f %f %f %f %f",
&numbers[0], &numbers[1], &numbers[2],
&numbers[3], &numbers[4], &numbers[5]);
/* Where do the numbers end... */
size_t numbers_end = strspn(line, "1234567890. \t");
/* And get the name */
char *name = line + numbers_end;
/* Do something with the numbers and the name */
}
Comments
-
slow almost 2 years
Let say I have a file looks like this
51.41 52.07 52.01 51.22 50.44 49.97 Coal Diggers 77.26 78.33 78.29 78.12 77.09 75.74 Airplane Flyers 31.25 31.44 31.43 31.09 31.01 30.92 Oil Fracting and Pumping 52.03 12.02 12.04 22.00 31.98 61.97 Big Bank 44.21 44.32 44.29 43.98 43.82 43.71 Rail Container Shipping 93.21 93.11 93.02 93.31 92.98 92.89 Gold Bugs
I want to read this file word using fscanf to put the numbers in float arrays and words in an array of strings. But, after few hours of strenuous thinking, I still can't figure out how to resolve this thing.
void dataInsert (COMPANY* company1, COMPANY* company2, COMPANY* company3, COMPANY* company4, COMPANY* company5, COMPANY* company6) { //Function Declaration FILE* spData; float number; char* name[20]; //Statement if ((spData = fopen("dataFile","r")) == NULL) { fprintf(stderr, "ERROR OPENING!!"); exit (1); } int i = 0; int numCount = 0; int lineCount = 0; while (fscanf(spData, "%f", &number) != EOF) { if(isdigit(number)) { if (lineCount == 0) { company1 -> stock_price[i] = number; } else if (lineCount == 1) { company2 -> stock_price[i] = number; } else if (lineCount == 2) { company3 -> stock_price[i] = number; } else if (lineCount == 3) { company4 -> stock_price[i] = number; } else if (lineCount == 4) { company5 -> stock_price[i] = number; } else if (lineCount == 5) { company6 -> stock_price[i] = number; } numCount++; i++; if (numCount == 6) { lineCount++; numCount = 0; i = 0; } } }//while fclose (spData); }//dataInsert
I don't know what to do with strings at the end of each line. I want to put those string in structure company -> name[10]. Those data are in a text file.
-
uba about 11 years
fscanf
is to be used instead ofscanf
, right? The input is not from stdin, it is from a file. -
steveha about 11 yearsSure, and
fgetc()
instead ofgetchar()
. I changed the answer. -
slow about 11 yearsIf I use scanf, does it just skip the strings at the end of each line?
-
steveha about 11 yearsAccording to the man page for
scanf()
, the format code%s
reads any sequence of characters that is non-white-space, and then stops when it hits white-space. Since the company names can have spaces in them, I thought it was easier to just loop until done rather than try to getscanf()
to do what we want. When you usescanf()
with the%f
format code, it will return a 0 to signal that the input didn't work as a float, and you will have some nonsense value in the float... probably a 0 or garbage, I haven't checked. You can try it if you like. -
slow about 11 yearsThanks for the reply but, unfortunately, I can't use sscanf since this is part of a school assignment so I have to do it based on what I have learned in class.
-
Some programmer dude about 11 years@ProgrammingNerd Never be afraid of "thinking outside the box"... You could do two solutions, one following the assignment to the letter, and then list possible shortcomings followed by a solution that solves the assignment but without the shortcomings.
-
Some programmer dude about 11 years@ProgrammingNerd Not that I'm saying that my solution is without shortcomings in itself, all solutions have pros and cons, including mine.
-
slow about 11 yearsYeah, I always try to solve problems in numerous ways, although it is the not best solution. That is what makes programming so interesting and fun! haha