Computer Science Canada

Scanning different lines

Author:  jamonathin [ Mon Jan 29, 2007 10:41 am ]
Post subject:  Scanning different lines

I have a problem that requires me to read input from multiple lines. Problem is, i dont know how long each line is going to be.
For example, the line can be from 1-50 numbers long, and the number of columns is terminated by -1, where each number is seperated by a space.

So an sample input could be:

1 2 3 4 5 6 7
2 3 4 5 6 7 8
4 5 6 7 8 9 0
-1

or it could be:

2 3 4 5
4 5 6 7
-1

So how do i know when the user hits enter, and moves on to the next line?

Author:  Monstrosity_ [ Mon Jan 29, 2007 5:49 pm ]
Post subject:  Re: Scanning different lines

jamonathin @ Mon Jan 29, 2007 11:41 am wrote:
So how do i know when the user hits enter, and moves on to the next line?

You get input. The input stream is buffered so you will not get anything until the user hits enter, then you get the line. You shouldn't be concerned about this since your are given an end of input delimiter. If you are asking for help on reading each number in until the delimiter is reached, I suggested you look over your input functions one more time.

HINT: new lines, tabs, spaces, etc are all white space.

Author:  jamonathin [ Tue Jan 30, 2007 11:47 am ]
Post subject:  Re: Scanning different lines

But the thing is I dont know how many white spaces the user will enter, because i'm supposed to be storing each row in a 2d array. See, i'm supposed to end up sorting the second, third ... n'th rows to look like the first row inputted. If the user doesn't tell me how long/(how many white spaces) the row will be, how am I supposed to find this out?

Basically how would you store:

1 2 3 4 5
5 1 2 3 4
5 4 1 2 3

In a 2d array? When thats all that is given from the user? (not knowing the row will be 5 numbers long)

Author:  Monstrosity_ [ Tue Jan 30, 2007 11:40 pm ]
Post subject:  Re: Scanning different lines

jamonathin wrote:

because i'm supposed to be storing each row in a 2d array. See, i'm supposed to end up sorting the second, third ... n'th rows to look like the first row inputted. If the user doesn't tell me how long/(how many white spaces) the row will be, how am I supposed to find this out?



Monstrosity_ wrote:

I suggested you look over your input functions one more time.

HINT: new lines, tabs, spaces, etc are all white space.


jamonathin wrote:

Basically how would you store

1 2 3 4 5
5 1 2 3 4
5 4 1 2 3

In a 2d array? When thats all that is given from the user? (not knowing the row will be 5 numbers long)

There's many ways.. you will need to decide if you want to set the upper limits (n,r) and have static memory for the array (array[n][r]) or dynamic memory that will grow as needed. You should stick with the former, then all you would need to do is read each value and store it as you go along from 0 to r-1. And also ensure no more then n lines are considered.

Author:  OneOffDriveByPoster [ Wed Jan 31, 2007 12:19 am ]
Post subject:  Re: Scanning different lines

jamonathin @ Mon Jan 29, 2007 10:41 am wrote:
So how do i know when the user hits enter, and moves on to the next line?


There are many ways. Try using ungetc().

Author:  Monstrosity_ [ Wed Jan 31, 2007 8:04 am ]
Post subject:  Re: Scanning different lines

OneOffDriveByPoster @ Wed Jan 31, 2007 1:19 am wrote:
jamonathin @ Mon Jan 29, 2007 10:41 am wrote:
So how do i know when the user hits enter, and moves on to the next line?


There are many ways. Try using ungetc().

Mind elaborating? I don't understand how pushing a character back onto the stream would help here.

Author:  OneOffDriveByPoster [ Wed Jan 31, 2007 11:19 am ]
Post subject:  Re: Scanning different lines

OneOffDriveByPoster @ Wed Jan 31, 2007 1:19 am wrote:
jamonathin @ Mon Jan 29, 2007 10:41 am wrote:
So how do i know when the user hits enter, and moves on to the next line?


There are many ways. Try using ungetc().

Monstrosity_ @ Wed Jan 31, 2007 8:04 am wrote:
Mind elaborating? I don't understand how pushing a character back onto the stream would help here.

One character look-ahead for finding '\n'.

Author:  Monstrosity_ [ Wed Jan 31, 2007 1:15 pm ]
Post subject:  Re: Scanning different lines

OneOffDriveByPoster @ Wed Jan 31, 2007 12:19 pm wrote:

Monstrosity_ @ Wed Jan 31, 2007 8:04 am wrote:
Mind elaborating? I don't understand how pushing a character back onto the stream would help here.

One character look-ahead for finding '\n'.


Ok, I get looking for the new line but why would you want to push it back onto the stream? That just seems bass awkwards to me.

Author:  OneOffDriveByPoster [ Wed Jan 31, 2007 3:44 pm ]
Post subject:  Re: Scanning different lines

Monstrosity_ @ Wed Jan 31, 2007 1:15 pm wrote:
OneOffDriveByPoster @ Wed Jan 31, 2007 12:19 pm wrote:

One character look-ahead for finding '\n'.


Ok, I get looking for the new line but why would you want to push it back onto the stream? That just seems bass awkwards to me.

Not to push back the newline, but to push back a non-whitespace character if one is read.

Author:  md [ Wed Jan 31, 2007 4:54 pm ]
Post subject:  RE:Scanning different lines

*sigh* tried reading an entire line (with say getline()); then parsing that line?

It's a ridiculously easy problem and I am surprised that it hasn't been solved yet.

psudo:

y = 0
do
        readline(&buffer)
        x = 0
        number == ""
        for i = 0 to length(buffer)
                if !whitespace(buffer[i])
                        concat(number, buffer[i])
                else
                        array[x++,y] = atoi(number)
                        number = ""
        y++
while !eof

Author:  Monstrosity_ [ Wed Jan 31, 2007 6:31 pm ]
Post subject:  Re: Scanning different lines

OneOffDriveByPoster @ Wed Jan 31, 2007 4:44 pm wrote:
Monstrosity_ @ Wed Jan 31, 2007 1:15 pm wrote:
OneOffDriveByPoster @ Wed Jan 31, 2007 12:19 pm wrote:

One character look-ahead for finding '\n'.


Ok, I get looking for the new line but why would you want to push it back onto the stream? That just seems bass awkwards to me.

Not to push back the newline, but to push back a non-whitespace character if one is read.

Doh! It was just me that was bass awkwards, I get ya now, thanks.

md wrote:

*sigh* tried reading an entire line (with say getline()); then parsing that line?

Reading the whole line is optional as OneOffDriveByPoster pointed out.

md wrote:

psudo:

y = 0
do
        readline(&buffer)
        x = 0
        number == ""
        for i = 0 to length(buffer)
                if !whitespace(buffer[i])
                        concat(number, buffer[i])
                else
                        array[x++,y] = atoi(number)
                        number = ""
        y++
while !eof



You psudo code mixes up two different ideas. If you grab the whole line, your are no longer worried about white space since you know where the new line is. If you decide to read the values from the stream, then you need to check white space so that you don't skip right over the new line character (which is what my hint was getting at). Also your psudo code is just flawed in general if values > 9 are allowed.

Author:  md [ Wed Jan 31, 2007 7:16 pm ]
Post subject:  RE:Scanning different lines

I think you'll find that my code does what it required; and it does it simply. Perhaps if you stopped to think about it...

Author:  Monstrosity_ [ Wed Jan 31, 2007 7:49 pm ]
Post subject:  Re: RE:Scanning different lines

md @ Wed Jan 31, 2007 8:16 pm wrote:
I think you'll find that my code does what it required; and it does it simply. Perhaps if you stopped to think about it...


psudo:


/* first iteration */
y = 0
do
        readline(&buffer)  /* "12 13 14" */
        x = 0
        number = ""
        for i = 0 to length(buffer) /* i = 0; length(buffer)=8;  */
                if !whitespace(buffer[i])
                        concat(number, buffer[i]) /* number = "12 13 14" */
                else
                        array[x++,y] = atoi(number) /* array[0][0] = 12 */
                        number = ""
        y++
while !eof

/* second iteration */
        for i = 0 to length(buffer) /* i=1 */
                if !whitespace(buffer[i])
                        concat(number, buffer[i]) /* number = "2 13 14" */
                else
                        array[x++,y] = atoi(number) /* array[1][0] = 2 */
                        number = ""
        y++
while !eof

/* last iteration */
        for i = 0 to length(buffer) /* i=8 */
                if !whitespace(buffer[i])
                        concat(number, buffer[i]) /* number = "" */
                else
                        array[x++,y] = atoi(number) /* array[6][0] = 0 */
                        number = ""
        y++


Given "12 13 14" your code should read in {12, 2, 13, 3, 14, 4, 0}? If I missed something feel free to correct me.

Author:  OneOffDriveByPoster [ Wed Jan 31, 2007 7:57 pm ]
Post subject:  Re: RE:Scanning different lines

md @ Wed Jan 31, 2007 7:16 pm wrote:
I think you'll find that my code does what it required; and it does it simply. Perhaps if you stopped to think about it...


Okay, yes, no leading or trailing whitespace and one space between each character. I don't like the buffer though. I guess anything else could be explained by it being pseudocode.

Author:  md [ Wed Jan 31, 2007 10:03 pm ]
Post subject:  RE:Scanning different lines

Monstrosity_ I am not at all sure what yoru comments mean... but from what I gather you are wrong.

As I'm sure wtd has mentioned before being able to trace code is a key part of programming... so try again and I'll tell you if your closer.

[edit] to clarify contat takes a string and a character and adds teh character to the string. whitespace returns true if hte passed character is a whitespace character. Those seem to be the things that people don't understand...

Author:  Monstrosity_ [ Wed Jan 31, 2007 11:50 pm ]
Post subject:  Re: RE:Scanning different lines

md @ Wed Jan 31, 2007 11:03 pm wrote:
Monstrosity_ I am not at all sure what yoru comments mean... but from what I gather you are wrong.

As I'm sure wtd has mentioned before being able to trace code is a key part of programming... so try again and I'll tell you if your closer.

[edit] to clarify contat takes a string and a character and adds teh character to the string. whitespace returns true if hte passed character is a whitespace character. Those seem to be the things that people don't understand...

Ahh, ok. I figured you meant strcat when you put concat. If a function concat were defined like that then yes I see this working fine, aside from the for loop stepping one to far and the mix of buffer/white space checking mentioned in previous post.

Author:  md [ Thu Feb 01, 2007 7:50 am ]
Post subject:  RE:Scanning different lines

Seems I cannot post anything big... but only in this thread.... weird.

Yes, in the original post it does read one too far, however the other thing you mention I am still not seeing.

Author:  Monstrosity_ [ Thu Feb 01, 2007 8:09 am ]
Post subject:  Re: RE:Scanning different lines

md @ Thu Feb 01, 2007 8:50 am wrote:
Yes, in the original post it does read one too far

I was wrong here (3rd brain fart in this thread, I quit), even though you read one to far the null character will be skipped by the white space check.

md @ Thu Feb 01, 2007 8:50 am wrote:
however the other thing you mention I am still not seeing.

What I mean is if your grabbing the whole line, you no longer care about checking the whitespace because you know the whole line will be stored in the same row of the array. This is important if your just reading from the stream so you know when to move to the next row of the array. When you go to use functions like strtol (or atoi, strtod, scanf, fscanf, etc) leading whitespace is skipped, making your white space checks superfluous.

Author:  md [ Thu Feb 01, 2007 4:57 pm ]
Post subject:  RE:Scanning different lines

see my code reads a line on input (which contains all the numbers) and then get's each individual number on the line and inserts it into the array... methinks maybe you didn't quite get that part?

Author:  jamonathin [ Sat Feb 03, 2007 11:43 am ]
Post subject:  Re: Scanning different lines

Hey thanks for all the inputs, lol. I pretty well figred it out. It's not so much I didn't know the algorithm, it was that I'm somewhat new to C so I didn't really know many commands of what C could do.

Basically what i did was i took a single character as input. If it was a space, I added 1 to the number in that row, if it was a digit I added that value to my array, then when the user entered "\n", i moved on to the next row.

It worked quite nice and I was able to take in 2+ digit numbers as well (checking if last char entered was a space or digit, then *10 and plus)

I tried your method md, but i kept getting errors cuz I couldn't get the proper syntax and whatnot down. That method too was my first choice, its much easer.

Thanks again for the input guys.


: