0

I want to read from two files, one containing floats in three columns, and another containing ints in two columns. I have the following code to read from stdin:

int main() { while (scanf("%lf %lf %lf\n",&x,&y,&z) != EOF) { // do stuff } puts("foo"); int a,b; while (scanf("%d %d\n",&a,&b) != EOF) { puts("bar"); } } 

Then I call the program with cat ortho.dat pairs.dat | ./angles, ortho.dat and pairs.dat being the two files. However the output is just foo indicating that the second file is never read, presumably because it reads EOF and immediately terminates the second loop. Is this correct?

How could I read the two files, without actually opening them in the program, merely reading them from stdin?

4
  • 2
    1. Decide on the programming language. 2.Pass the file names into the application can not use cat. 3. Read those files - that depends on the programming language Commented Mar 5, 2015 at 20:31
  • I forgot to mention it in the post itself, but the language is C++, as stated in the title and the tags. I also specifically said that I wanted to know how to do this from the shell, without files. That I know how to do :) Commented Mar 5, 2015 at 20:36
  • So why C in the title and tags if it is C++? Commented Mar 5, 2015 at 20:37
  • 3
    @andrepd I've retagged your question per your comment, however your question is more appropriate to C as you're not using C++ idiom. I HIGHLY suggest you pick the language for the idiom you intend to use. Commented Mar 5, 2015 at 20:43

3 Answers 3

3

Question:

How could I read the two files, without actually opening them in the program, merely reading them from stdin?

One solution:

Insert dummy, invalid, content between the contents of two files. Use it to separate the data from the first file and the second file.

Contents of file "dummy":

===Separator=== 

Change your code to:

int main() { while (scanf("%lf %lf %lf\n",&x,&y,&z) == 3) { // do stuff } // Skip the line that contains the separator. scanf("%*[^\n]"); puts("foo"); int a,b; while (scanf("%d %d\n",&a,&b) == 2) { puts("bar"); } } 

Change the invocation:

cat ortho.dat dummy pairs.dat | ./angles 

Update

A C++ version:

int main() { while ( std::cin >> x >> y >> z ) { // do stuff } // Skip the line that contains the separator. std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); puts("foo"); int a,b; while ( std::cin >> a >> b ) { puts("bar"); } } 
Sign up to request clarification or add additional context in comments.

Comments

2

When you do "cat F1 F2 | program", cat will concatenate the files and the program will receive single continuous stream of data.

From the point of view of the program it is impossible to find where one file ends and second begins unless some marker inserted into the files.

For example, you can insert a single line after the first file saying: FILE1ENDS Then, if such a line would never be found in the file itself you can use that to terminate your first loop.

As an alternative pass file names as arguments to your program and open/read/close them yourself.

Comments

2

You can't do that reliably. Read about fscanf(3) (it handles every space-like character the same, including newlines). BTW, you'll better test that scanf returns the actual count (e.g. 3 for the first case, 2 for the second one).

However, you might have more constraints on the input. Perhaps the three doubles and the two integers are always on a single same line, e.g. ortho.dat containing lines like

1.0 2.0 3.0 

and pairs.dat containing lines like

23 45 

then you could read every line using getline(3) (or perhaps fgets) and use sscanf to parse it (and you would use its return count to separate the lines with 3 floating points from the lines with 2 integers). The %n control format could perhaps be handy (it gives the current cursor position).

However, I would instead suggest to pass the two file names ortho.dat & pairs.dat as distinct arguments (i.e. use the conventional argc & argv arguments to main(int argc, char**argv))

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.