Thread: Saving each line of a file

  1. #1
    Registered User
    Join Date
    Nov 2009
    Posts
    37

    Saving each line of a file

    Hi,

    I have a txt file with some specifications on building a grid map. The file has already been opened in a FILE stream, but I'm having some difficulty trying to sort of extract the contents of the file stream (line-by-line).

    Example:
    Code:
    2
    2
    1 2 4 2 2 2
    2 1 4 2 2 3
    2 2 4 2 2 1
    This is saying I have a 2x2 grid map, with 2 tracks per path (or channel). The remaining three strings of numbers are basically description of element placements on the 2x2 map. Example: 1 2 4 2 2 2 says element (1,2) has outlet 4 connected to inlet 2 of element (2,2). This file can of course have hundreds of such lines describing element placement.

    So my problem is that I need to have each line and convert that string to an integer; save it somewhere so it can be referenced for building the grid map when the praising of the file is finished.

    Thank you.

  2. #2
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Get familiar with fgets and sscanf. We're not really here to do everything for you--unless we're incredibly bored, which I am not at the moment.


    Quzah.
    Hope is the first step on the road to disappointment.

  3. #3
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    Post up your code for this, and tell us what the specific problem is.

    Sure, we could code it up for you, but you won't learn anything by that (and we'll be buried 20 meters in such requests, in no time.)

    So help us avoid becoming "free programming central", and help yourself, all at the same time. Try it!

  4. #4
    Registered User
    Join Date
    Nov 2009
    Posts
    37
    I'm putting it in a while loop as follows:
    Code:
    while(fgets(buff, sizeof (buff), netlist) != NULL)
    I wanted to place something like strtoul(buff, NULL, 10) in the while loop, but it only converts the first number of each line.
    I'm unsure how to implement it using sscanf(). In particular because the lines are not always of constant size. The first two lines is one character each, while the remaining lines are 6 characters each.

  5. #5
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    Quote Originally Posted by user_name_void View Post
    I'm putting it in a while loop as follows:
    Code:
    while(fgets(buff, sizeof (buff), netlist) != NULL)
    I wanted to place something like strtoul(buff, NULL, 10) in the while loop, but it only converts the first number of each line.
    I'm unsure how to implement it using sscanf(). In particular because the lines are not always of constant size. The first two lines is one character each, while the remaining lines are 6 characters each.
    Forget strtoul(), in my opinion, you don't need it.

    sscanf() will do just what you want. It works very much like scanf(), but it works on strings as it's source, not stdin.

    Now you're working it - don't go wimpy - no one is sure how to use sscanf() or any other C function, until *after* they've worked with it.

    Handling 2 lines of one char, and the rest of the lines have 6 char's,

    C'mon! TRY!!

    Some idea's - this is not code, and will not run as is. It's a rough idea for you

    Code:
    input line 1
    sscanf() your first number
    input line 2
    sscanf() your second number
    
    while((fgets() ) != NULL) {
       fgets() your next line
       sscanf() your next set of numbers
    }
    What to save the numbers in, is another matter. It would be great to use an array of int's. Heaven help us if the numbers need to be bit packed.

    What's a maximum number of lines for these 6 digit rows? How much memory do you have, and what is your compiler?
    Last edited by Adak; 12-10-2009 at 09:36 PM.

  6. #6
    Registered User
    Join Date
    Nov 2009
    Posts
    37
    Okay, so here is how I see it. fgets() reads one line at a time. Therefore, it has to loop N times to get to line N. So my first two lines each have one characters. In my first while loop, I only loop once to get the first line.
    Code:
    while (i<1)
    	{
    		fgets(buff, sizeof (buff), file_stream);
    		puts(buff);
    		sscanf(buff, "%d", &a);
    		printf("grid is %d\n", a);
    		i++;
    	}
    The weird thing is that puts() has no output (a blank line) and the value stored from sscanf() is 0.

    There can be as much as 4000 lines of these guys (6 digits). Compiler is GCC on Linux and lets say we are designing for 1GB (worst case). I have 3BG, but then I have to build the map, and run an algorithm on it, so I will need the rest.

  7. #7
    Registered User
    Join Date
    Dec 2009
    Location
    /dev/pts/0
    Posts
    29
    Is buff a pointer? If so, then sizeof(buff) will return sizeof(char *) . . . probably not what you want.

    Beyond that, that snippet looks fine to me . . .
    -- strange

    There is no Darkness in Eternity
    Only Light too dim for us to see

  8. #8
    Registered User
    Join Date
    Nov 2009
    Posts
    37
    Quote Originally Posted by strange View Post
    Is buff a pointer? If so, then sizeof(buff) will return sizeof(char *) . . . probably not what you want.

    Beyond that, that snippet looks fine to me . . .
    buff is actually declared as:
    char buff[100];

  9. #9
    Registered User
    Join Date
    Dec 2009
    Location
    /dev/pts/0
    Posts
    29
    Check the return value of fgets()? Perhaps the stream is closed for some reason, or invalid, or not opened correctly . . .

    Beyond that, I can't say anything else without more code.
    -- strange

    There is no Darkness in Eternity
    Only Light too dim for us to see

  10. #10
    Registered User
    Join Date
    Nov 2009
    Posts
    37
    Well here is some self discovery I made:

    I have two while loops now. They are the same as that posted in post #6. They only thing that changes is the variable that sscanf() uses. But in order to get to the second line, I only looped once in the second while loop and not twice as I had first thought. Also, before doing any looping I have a line that prints out the contents of the txt file to stdout. When this line is compiled with the code, sscanf() always stores a value of 0 for both lines. When it is commented out, it works as just described. Are these behaviors normal that I am experiencing?

  11. #11
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    You can get ALL your 6 numbers with one line, using sscanf(), and you should do that.

    not one %d, use six %d's, all in the same line.

    Try using the stack with your compiler and see if it will give you the memory for that large array:

    int numbers6[4000][6];

    If that doesn't work, we'll use calloc() and get the memory from the heap part of memory.

  12. #12
    Registered User
    Join Date
    Nov 2009
    Posts
    37
    I seem to be making some progress. The first two lines are saved. Now I'm tackling the lines with 6 characters. I'm using an infinite for() loop:
    Code:
    for(;;)
    		{
    			fgets(buff, sizeof (buff), file_stream);
    			sscanf(buff, "%d %d %d %d %d %d", &a,&b,&c,&d,&e,&f);
    			printf("first row is %d %d %d %d %d %d\n", a,b,c,d,e,f);
    			if(a == -1) break;
    		}
    I can see two issues here. The first one is how am I to store all the characters of each line so they can be accessed in the future. And the second one is, I really dont need the "-1" row to build my map, I just included it there for testing to break the for() loop. But it still gets saved. I would like to avoid that.

  13. #13
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by user_name_void
    The first one is how am I to store all the characters of each line so they can be accessed in the future.
    Why would you want to do that when you have already read the data into variables of integer type?

    Quote Originally Posted by user_name_void
    And the second one is, I really dont need the "-1" row to build my map, I just included it there for testing to break the for() loop. But it still gets saved. I would like to avoid that.
    Make use of the return values of the input reading functions in the loop condition, e.g.,
    Code:
    while (fgets(buff, sizeof(buff), netlist)
        && sscanf(buff, "%d %d %d %d %d %d", &a, &b, &c, &d, &e, &f) == 6)
    {
        printf("first row is %d %d %d %d %d %d\n", a, b, c, d, e, f);
    }
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  14. #14
    Registered User
    Join Date
    Nov 2009
    Posts
    37
    Quote Originally Posted by Adak View Post
    You can get ALL your 6 numbers with one line, using sscanf(), and you should do that.

    not one %d, use six %d's, all in the same line.

    Try using the stack with your compiler and see if it will give you the memory for that large array:

    int numbers6[4000][6];

    If that doesn't work, we'll use calloc() and get the memory from the heap part of memory.
    Thats quite a lot of memory, especially since I will be running the program over-and-over for testing. Would I have to do anything special in terms of mem management to free up that memory when the program is finished?

  15. #15
    Registered User
    Join Date
    Dec 2009
    Location
    /dev/pts/0
    Posts
    29
    If you declare the array as a variable on the stack (e.g. as a local or global variable), then you will not have to do anything unusual to the variable to free it. Only memory allocated on the heap, using calloc() as Adak suggests, has to be freed specially.

    However, there's probably a better way to do it. That, for example, is hard-coding a limit of 4000 elements -- what if you want to scale up to 8000? or 10000? Or what if you are only using the first twelve? . . .

    I will repeat what laserlight has said -- why do you wish to store the string for later retrieval? You are extracting all of the data from it already . . . if absolutely required, you can re-assemble the string from the numerical data . . .
    -- strange

    There is no Darkness in Eternity
    Only Light too dim for us to see

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Newbie homework help
    By fossage in forum C Programming
    Replies: 3
    Last Post: 04-30-2009, 04:27 PM
  2. Need Help Fixing My C Program. Deals with File I/O
    By Matus in forum C Programming
    Replies: 7
    Last Post: 04-29-2008, 07:51 PM
  3. Replies: 3
    Last Post: 03-04-2005, 02:46 PM
  4. Trouble replacing line of file
    By Rpog in forum C Programming
    Replies: 4
    Last Post: 04-19-2004, 10:22 AM
  5. simulate Grep command in Unix using C
    By laxmi in forum C Programming
    Replies: 6
    Last Post: 05-10-2002, 04:10 PM