3

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.

8
  • 1
    Are you sure you want to read the values as integers and not floating point? Also, please show us what you have tried. Commented Mar 9, 2013 at 2:02
  • Are those actual <br> tags in the file? Is this file XML or HTML or something? Maybe you should use a parsing library? If the file is exactly the format you show here, you can parse it with C, but a scripting language would be easier... Python would be my choice. Commented Mar 9, 2013 at 2:05
  • 2
    Is your file always organized like that? With the same number of numbers before the string? Or do you have to detect whether what you're reading is a number or string? Commented Mar 9, 2013 at 2:11
  • 1
    scanf is not a very robust way to read a file, because if the formatting is changed even somewhat it will fail. Commented Mar 9, 2013 at 2:22
  • @Douglas B. Staple Then what do you recommend? Commented Mar 9, 2013 at 2:24

2 Answers 2

4

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 */
}
Sign up to request clarification or add additional context in comments.

4 Comments

Thanks 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.
@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.
@ProgrammingNerd Not that I'm saying that my solution is without shortcomings in itself, all solutions have pros and cons, including mine.
Yeah, 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
2

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.

4 Comments

fscanf is to be used instead of scanf, right? The input is not from stdin, it is from a file.
Sure, and fgetc() instead of getchar(). I changed the answer.
If I use scanf, does it just skip the strings at the end of each line?
According 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 get scanf() to do what we want. When you use scanf() 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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.