2

I am newbie in C++.

I got an ASCII file of 3 columns and 143 rows. First column has integer numbers while the rest of the two columns have floats.

Goal: Store individual three columns into three Arrays of size 143, each.

Problem: When print using cout, the last row is repeated, I don't know why.

ASCII file sample:

2   41.3    25
2   46.2    30
2   51.5    40
2   56.7    45
3   49.5    525
3   46.2    450
3   54.0    575
3   59.5    650
5   36.0    500
5   39.0    525
5   31.8    480
5   36.4    520

And my code:

void my_code()
 {
    FILE *pfile;
    int ball[150];
    float energy[150], channel[150];
    int ball1[150], i=0;
    float energy1[150], channel1[150];
    pfile = fopen("./ascii.txt","r");
    if (!pfile) continue;
    while(!feof(pfile))
    {
      fscanf(pfile,"%d\t%f\t%f",&ball[0],&energy[0],&channel[0]);
      ball1[i]=ball[0];
      energy1[i]=energy[0];
      channel1[i]=channel[0];      
      cout<<i<<"\n";
      cout<<ball1[i]<<" "<<" "<<energy1[i]<<" "<<channel1[i]<<"\n";
      i++;
     }
 }

Please help me to understand. I am also willing to get suggestions/advices for improvement of my code.

3 Answers 3

1

First of all your code shall not be compiled because using the continue statement outside a loop is invalid.

if (!pfile) continue;

So I wonder why your code is compiled. As for repeating of values of the last line of the file then it is due to that during a next iteration of the loop the reading of the next line was finished with state EOF and values of ball[0],energy[0], and channel[0] were not changed. They keep their previous values.

Also there no any sense to declare arrays ball[0],energy[0], and channel[0] if you use only the first one element of them.

It is also unclear why you mix up C++ and C code. In fact the function does nothing except it outputs values extracted from the file. So there is no any sense to define arrays.

My code that would do the same would look the following way

#include <iostream>
#include <fstream>
#include <sstream>
#include <string>

//...

void my_code()
{
    std::ifstream file( "./ascii.txt" );

    std::string line;

    while ( std::getline( file, line ) )
    {
        std::istringstream is( line );
        int v1;
        float v2, v3;

        if ( is >> v1 ) 
        {
            std::cout << v1;
            if ( is >> v2 ) 
            {
                std::cout << ' ' << v2;
                if ( is >> v3 )
                {
                    std::cout << ' ' << v3;
                }
            }
            std::cout << std::endl;
        }
    }
}             

If you need to have arraya then the code can look as

#include <iostream>
#include <fstream>
#include <sstream>
#include <string>

//...

void my_code()
{
    const size_t N = 143;
    int ball[N] = {};
    float energy[N] = {};
    float channel[N] = {};

    std::ifstream file( "./ascii.txt" );

    std::string line;

    size_t i = 0;    
    while ( i < N && std::getline( file, line ) )
    {
        std::istringstream is( line );

        if ( is >> ball[i] ) 
        {
            std::cout << ball[i];
            if ( is >> energy[i] ) 
            {
                std::cout << ' ' << energy[i];
                if ( is >> channel[i] )
                {
                    std::cout << ' ' << channel[i];
                }
            }
            std::cout << std::endl;
        }
    }
}             
Sign up to request clarification or add additional context in comments.

7 Comments

Your code doesn't work even after correcting the closing brace "]" to "}" at the 3rd "if-loop". Here is the error message: my_code.C: In function ‘void my_code()’: my_code.C:10:48: error: no matching function for call to ‘std::basic_ifstream<char>::basic_ifstream(const char [17], const char [2])’
@Gunn it was a typo due to "copy and paste". I updated the code.
And, I am not restricted to C++ code, I can use C as well, ultimately I need the work done. Here indeed I need to create ARRAYS as I have explicitly specified in my "GOAL". Another answer by "thb" below helped me to solve the problem.
@Gunn You did not use the array. So it is not clear the purpose of the function. But in any case you can create an array. there is need minor changes.
I am using Ubuntu 12.04 linux, and the code you provided doesn't work with any of the compiler (gcc, g++, gfortran), but it does work withing a c++ based Physics anlysis program called root (root.cern.ch). So I suppose that your code is either missing some header in the top starting with "#include" or it is not suitable for Linux. I am newbie so i might not be correct. The error I get is as following: ----> [SEE MY NEXT COMMENT]
|
0

Your trouble lies in the position of your loop test within the loop. Try this, instead:

while(true)
{
  fscanf(pfile,"%d\t%f\t%f",&ball[0],&energy[0],&channel[0]);
  if (feof(pfile)) break;
  ball1[i]=ball[0];
  energy1[i]=energy[0];
  channel1[i]=channel[0];      
  cout<<i<<"\n";
  cout<<ball1[i]<<" "<<" "<<energy1[i]<<" "<<channel1[i]<<"\n";
  i++;
}

Newcomers to programming often err in this way. Your loop is actually pretty good for an early attempt, but do consider precisely the point from which a loop wants to exit. If your exit point is off, you'll get odd effects on the loop's final iteration.

Once you understand the answer, be advised that many programmers used to deprecate (and some still deprecate) the style of breaking a loop from the midst of the loop action. That is, some programmers used to tend not to like break. Personally, after three decades of programming, I usually disagree with the deprecation, but if you have a programming instructor who dislikes break, you should naturally take the instructor's preference into account.

1 Comment

I am pleased that the answer helps. The usual Stackoverflow procedure when an answer helps is (a) to upvote it (click on the up-arrow by the answer) and (b) if it is the most helpful answer, to accept it (click on the checkmark next to it).
0

You can check the return code of fscanf for correctness and exit the loop if there is an error

while (!feof(fp)) {
  ...
  ret = fscanf(pfile,"%d\t%f\t%f",&ball[0],&energy[0],&channel[0]);

  if (ferror(fp) || (ret == EOF)) {
    // handle the error
    break;
  } 
  ...
}

Comments

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.