Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

Homework Help: Reading separate lines from txt file (C code)

  1. Mar 24, 2010 #1
    1. The problem statement, all variables and given/known data

    I want to read each line separately in a char array from a text file. As yet, the best I could do is to read the entire file in a single char array. How can I read each line in a separate array?

    2. Relevant equations



    3. The attempt at a solution

    Code (Text):

    #include <stdio.h>

    int main()
    {
        FILE *f;
        char s[1000];

        f=fopen("infile","r");
        if (!f)
            return 1;
        while (fgets(s,1000,f)!=NULL)
            printf("%s",s);
        fclose(f);
        return 0;
    }
     
    The file is a mixture of chars, ints, spaces and tabs. Here's what the file contains:

    p1 0
    12 2 21 2 13 32 18
    p2 9
    13 17 3 21 45 67 21
    p3 34
    12 3 43 24 3 43 23 12 32 12 35 3
    p4 178
    12 32 42 32 3 32 32 2 54 64 2
    p5 250
    44 43 11 32 78 123 32 324 432 21 123 231 23 123
    p6 689
    12 324 423 324 543 23 53 44 62 43 432 23 122 32

    Thanks.
     
  2. jcsd
  3. Mar 24, 2010 #2
    Here's the further code. I've succeeded in reading the first line and following is the code:

    Code (Text):

    #include <stdio.h>
    #include <string.h>

    struct Process
    {
    char process;
    int arrival;
    int bursts[50];
    };

    void Get ();

    void Get ()
    {
        struct Process pro;
        FILE *f;
        int i=0,j=0;
        //char arr[50];
        //char arr2[50], arr3[50], arr4[50], arr5[50];
        printf ("Data outptut\n");
        char s[500];
        int count = 0, count2 = 0, count3 = 0, count4 = 0, count5 = 0;
        int spacecount=0;
        f=fopen ("umer.txt","r");
        if (!f)
        printf ("Could not open the file.\n");

    ////////////////////////////////////////////////////////////////////////

        while (fgets (s,1000,f)!=NULL)
        {
            if (s[i] == 'P' && s[i+1] == '1')
            {

                if (s[i+2] == '\t')
                {  
                    pro.arrival =(int)s[i+3]-'0';
                    printf ("Arrival time of process P1: %d\n", pro.arrival);
                i=i+4;

                }      
            }

            while (s[i]!='\n')
            {
                //printf ("%d\n", i);
                count++;
                fscanf(f, "%d", &pro.bursts[i]);
                //printf ("%d", pro.bursts[i]);
                //i++;
            }

            printf ("%s", s);
        }
    printf ("\n");
    fclose(f);
    }

    int main ()
    {
        Get();
        return 0;
    }
     
    But I'm not able to read the integers in the second line. I want to read the integers in an integer array from the second line.

    P.S= I know my coding skills are not good so kindly save me the embarrassment and help me out. I'd be highly obliged.

    Thanks.
     
  4. Mar 24, 2010 #3

    Mark44

    Staff: Mentor

    Your program probably won't know how many lines are in the data file, so you can't declare a number of arrays at compile time, and fill each of them with one line of input.

    To get around this problem you can allocate storage from the heap. You can write a loop that
    1. reads a line of input.
    2. Allocates a block of memory using a memory allocation function such as malloc().
    3. Stores the address of the block of memory somewhere for later use.

    To use this technique you should be very familiar with pointer usage, since that's how you will need to access each of your blocks of memory.
     
  5. Mar 24, 2010 #4
    Can you help me with a little initial code for dynamic storage of line? (I'm confused how to start with that!)
     
  6. Mar 24, 2010 #5
    So what is the point of reading the entire file into memory? I don't think it is really necessary to do that.

    What you need to know is that each line will be random characters, but will always end with a '\n' (newline character).

    Read the line until you come accross a '\n' and then you know that's one line.

    The end of a file will have a 'EOF'.

    If you just need to process each line, then read in one line at a time, process it, throw it away. Using the same arrays you won't need to take up too much memory.
     
  7. Mar 24, 2010 #6

    Mark44

    Staff: Mentor

    That's a good question, NoUse. On another point, Peon666 doesn't need to be concerned about newline chars since he is using fgets, which reads a line of text (up to the \n char).
     
  8. Mar 25, 2010 #7
    Alright, how should I modify the following line to get only till the end of line and not the entire file?:

    while (fgets (s,1000,f)!=NULL)
     
  9. Mar 25, 2010 #8
    Besides, what does this function do:

    scanf ('\n');

    Does this make the pointer start reading from the next line? (after the end of the first line). This is the critical problem I'm having basically. I read the first complete line but after that I'm not able to read the next line because the pointer stars reading the whitespaces even after the line had ended.
     
  10. Mar 25, 2010 #9

    Borek

    User Avatar

    Staff: Mentor

    fgets gets a single line, not an entire file.

    There are some quirks possible depending on whether the file is opened in text or binary mode.
     
  11. Mar 25, 2010 #10

    Mark44

    Staff: Mentor

    That's what fgets does - read a line of characters. It copies characters from the input stream to the array, and stops copying when it reaches a newline character, or the end-of-file marker, or when it has copied one less character than the middle parameter specifies. It stores a null character after the last character in the string.

    In your line of code above, you probably aren't going to encounter any lines that are 1000 characters long, so you can reduce that number to something more appropriate.
     
  12. Mar 25, 2010 #11

    Mark44

    Staff: Mentor

    I have no idea what this does, but I'm pretty sure nothing good. Since you are using standard I/O functions such as scanf and fgets, you should read the documentation for these functions so that you can use them correctly.
     
  13. Mar 25, 2010 #12
    Here's a further piece of the code and a problem related to it:

    Code (Text):

    int j=49;
    int check;
    char a;f=fopen ("umer.txt","r");
    if (!f)
          printf ("Could not open the file.\n");
    check = j%2;
    while (fgets (s,1000,f)!=NULL)
    {
          if (j%2 != 0)
          {
                if (s[i] == 'P' && s[i+1] == j)
                {
                      if (s[i+2] == '\t')
                      {
                             pro.arrival =(int)s[i+3]-'0';
                             printf ("Arrival time of process P%d: %d\n",j-'0', pro.arrival);
                             i=i+4;
                             fscanf (f, "%c", &a);
                       }
                 }
          }
          j++;
          printf ("%d ", j);
    }

    Consider these lines in the file:

    p1  0
    12  2   21  2   13  32  1
    p2  9
    13  17  3   21  45  67  21
    p3  34

    Now, through the above code, I'm able to read P1 and it's time, i.e 0. But after that, I think it should run for all Ps and there corresponding time given in front of them. But after running for the first process, the loop does not go any further.

    What's the problem in the above code?

    //printf ("%s", s);
    }
     
     
  14. Mar 27, 2010 #13

    Mark44

    Staff: Mentor

    I took the liberty of moving your question and comment out of the code block.
    Comments:
    1. In the line with fgets, you are attempting to read in up to 1000 characters. Your input file is unlikely to have that many characters in one line.
    2. What happens if f == 0? The code will print "Could not open the file.\n", and this is good, but it will continue executing the next line after that, and this is not good.
    3. The i variable seems to be both undeclared and undefined. If i is undeclared, the compiler will issue an error. If i is declared by undefined, the values in i, i + 1, and i + 2 will be garbage, so there's no telling what will happen when you try to read s, s[i + 1], and s[i + 2].
      [*]The first time through your code, you are apparently looking for P1. You should probably be looking for P0 the first time through, based on your description of the data file.
      [*]The line i = i + 4; replaces the garbage value in i by garbage + 4, which is still garbage.
      [*]The fscanf line inputs a single character into the variable a. I don't understand the purpose of fscanf here.


    I think your best course of action is to start fresh with a new algorithm. Since your data is formatted in a certain way, and consists of alpha characters (the Ps) and numbers, it's might be better to use fscanf for lines the odd lines (lines 1, 3, 5, and so on), and something else for the even lines.

    You haven't said what your program will do with the data in the even-numbered lines. What information do you have about the even-numbered lines. In your example, the 2nd and 4th lines both have 7 numbers in them. Is that always the case? If not, do these lines have a minimum number of numbers and a maximum number of numbers? The code you write has to take this into consideration.

    To formulate your algorithm, it would be helpful to write down, in words, what your program needs to do with the data. From that description it will be much easier to write the code that does that. Trying to write code without a clear understanding of what the code needs to do is a complete waste of time.

    You should think of the computer as a very stupid, but very fast machine. It will do exactly what you tell it to do, but if you don't understand what it needs to do, you will not be able to give it the instructions to do what you want it to do.
     
Share this great discussion with others via Reddit, Google+, Twitter, or Facebook