C/C++ C++: Pass Numbers Into x & y Arrays from txt File

  • Thread starter Thread starter ChrisVer
  • Start date Start date
  • Tags Tags
    File Input Text
AI Thread Summary
The discussion revolves around reading data from a text file into arrays in C++. The original code fails to populate the arrays correctly due to not resetting the file stream after the first read loop. The solution involves closing and reopening the file or using a method to rewind the file pointer. It is also suggested to use vectors instead of arrays for dynamic sizing, which simplifies the code by eliminating the need to determine the array size beforehand.Additionally, participants discuss how to handle file paths for input files. The correct approach is to use command-line arguments to specify the file path when executing the program. This allows for flexibility in choosing different file locations without modifying the source code. The conversation highlights the importance of understanding relative versus absolute paths and the need to handle potential spaces in file paths when using command-line inputs. Overall, the thread provides practical coding advice for file handling in C++.
ChrisVer
Science Advisor
Messages
3,372
Reaction score
465
I know this is pretty basic question, but something doesn't seem to work right for me...
Suppose I have a txt file, with the following input:
Code:
x    y
0.0    0.5
1.0    1.5
2.0    4.8
3.0    4.9
How can I pass those numbers into x and y arrays using a C++ code?
My code so far is like this:

C:
#include<iostream>
#include<fstream>
using namespace std;

int main(){
//read file
ifstream finput;
finput.open("data.txt");

// part to calculate the dimensionality
int N=0;
double temp;
while(! finput.eof() ){
    finput >>tempp;
    N++;
}
N=N/2;//part to fill the arrays
double x[N];
double y[N];
int m=0;
while(! finput.eof() ){
    finput >>x[m]>> y[m];
    m++;
}

system("pause");
return 0;
}

But it seems that the 2nd loop doesn't put my values for x,y's into the corresponding arrays. The filled elements are extremely small numbers which I didn't even input.
Any feedback?
 
Technology news on Phys.org
Don't you need to rewind the file between loops? Close and reopen for example. I suspect what you've got in the array is just nonsense that happens to be in the (uninitialised) memory that you allocated.

Easy check - debugger, or add a printf inside the second loop and see if it's being executed at all.

Edit: I think >> will automatically convert the string read from the file to a double - but it may be worth checking that parsing is happening if the above doesn't fix it.
 
Ibix said:
Don't you need to rewind the file between loops? Close and reopen for example. I suspect what you've got in the array is just nonsense that happens to be in the (uninitialised) memory that you allocated.

Easy check - debugger, or add a printf inside the second loop and see if it's being executed at all

I tried to close/open the file inbetween the loops... it worked after doing it... :confused:confused!
 
Is that an "I was confused" or an "I am confused"?

In case of the latter, your first loop exits when finput.eof() is true. You didn't tell finput to return to the start of the file or anything, so it simply carried on reporting that it was at the end of the file (i.e. finput.eof() remained true) and the second loop exited immediately. Closing and reopening the file moves you back to the beginning. If ifstream has a rewind() method (or something similar) you could use that to achieve the same result.
 
  • Like
Likes ChrisVer
Try using vectors instead of arrays. You can add data to them so that they automatically grow to the size you need, instead of having the declare the size in advance. You don't have to read the file twice, first to find out how big to make the array, then to read the data. Here's a simple example that reads ints from a file into a vector and then displays the vector's contents:

Code:
#include <iostream>
#include <fstream>
#include <vector>

using namespace std;

int main ()
{
  vector<int> numbers;  // has length zero, initially

  ifstream inputfile ("data.txt");
  if (!inputfile)
  {
    cout << "Couldn't open data.txt!" << endl;
    return 0;
  }

  int n;
  while (inputfile >> n)  // loop terminates at end of file
  {
    numbers.push_back(n);  // append n to the vector and expand
                           // the vector as necessary
  }

  // the size() member function tells you how big the vector is

  cout << "The numbers are:" << endl;
  for (int k = 0; k < numbers.size(); ++k)
  {
    cout << numbers[k] << endl;
  }

  return 0;
}
 
  • Like
Likes Ibix
Here's another problem with your code. Your file begins with a header line containing text ("x y"). When your program tries to read a double from that line, the input stream goes into "fail" status, and you can't read anything further until you reset the stream status. To skip past that header line, read some text instead.

Code:
#include <string>

// ...

string head1, head2;
cin >> head1 >> head2;   // each '>>' reads one "word" at a time
                         // (sequence of characters delimited by whitespace)

// Now start reading the doubles
 
Last edited:
  • Like
Likes ChrisVer
Hey, thanks for the replies, they were understandable.
I would also like to ask a further question:
How can I feed in the txt file path in the terminal window??
suppose that I have the following paths:
[my code's path]/data.txt (I call it default)
[my code's path]/folder/data.txt (or any other path)

How can I use a non-default path for this code to run?
What I've been thinking is for a source code of the form:

C:
#include<string>

int main( int argc, char ** argstr){
    string fpath;
    if (argc==0)  fpath = "data.txt"; // have no command line arguments get the default
    else{
        fpath="";
        for(int i=0; i< argstr.size(); i++){
            fpath += argstr[i];
        }
    }
}

//REST OF CODE
 
ChrisVer said:
How can I use a non-default path for this code to run?
In the 'open' statement or the fstream constructor (as I did), specify either a relative path starting from your current location (in your example that would be folder/data.txt, with no slash at the beginning), or an absolute path starting from your file system root (which depends on your operating system).
 
jtbell said:
In the 'open' statement or the fstream constructor (as I did), specify either a relative path starting from your current location (in your example that would be folder/data.txt, with no slash at the beginning),.

Well yes, that would be the manual thing to do, which would require every time I wanted to change the path to enter my source code and change the filename in the fstream's constructor.
My point however is when I type this in the command line of the terminal:
./main
the code to run with the default path, and process the : "data.txt".
But when I type:
./main /folder1/xydata.txt
it would run on the txt file in the given path.
 
  • #10
jtbell said:
r an absolute path starting from your file system root (which depends on your operating system).
I don't really understand what this means... sorry if the answer to my question lies on this part of your post.
 
  • #11
Under Mac OS, I have a Documents folder, the default location for new files, which has the absolute path /Users/jtbell/Documents. If I have a program in that folder, and a data file data.txt which is also in that folder, I can open the file using either 'data.txt' or '/Users/jtbell/Documents/data.txt'. If the file is actually in a sub-folder named 'folder', I can use either 'folder/data.txt' or '/Users/jtbell/Documents/folder/data.txt'. In both examples, the first path is "relative" and the second path is "absolute."

But now I see that what you want is to specify the file name when you execute (run) the program, not as part of the source code. To do it like you said in post #9, you need to know how to process command-line arguments in C++. I haven't done this in a long time, so I'm not a good person to ask. I would have to re-learn it. Maybe someone else can contribute an example. Or if you Google for something like "c++ command line arguments" you'll probably find something.
 
  • Like
Likes ChrisVer
  • #12
jtbell said:
But now I see that what you want is to specify the file name when you execute (run) the program, not as part of the source code. To do it like you said in post #9, you need to know how to process command-line arguments in C++. I haven't done this in a long time, so I'm not a good person to ask.
@ChrisVer, what OS are you using? Are you running your code from the command line or from inside a debugger?

As an alternative to passing the path as a command-line argument, you could prompt the user to enter the path to the data file, and then to enter the name of the data file.
 
  • #13
Mark44 said:
prompt the user to enter the path to the data file, and then to enter the name of the data file.
...and then the program reads the name into a string, and you use the string as the argument to finput.open() or the constructor for finput.

A potential complication here is that finput.open() and the constructor both expect to receive C-style char* "strings" as arguments. If you read the filename into a C++ string, you have to do a conversion.

Code:
string filename;
cout << "File name? ";
cin >> filename;
ifstream finput;
finput.open(filename.c_str());

Or you can combine the last two statements into

Code:
ifstream finput (filename.c_str());
 
  • #14
Regarding the code in post #7 to get a file name from the command line:

The command line inputs can be received as an array of strings, argv[0], argv[1], argv[2], ... in the standard way with

int main(int argc, char*argv[]){

argv[0] is the path to the program you are running.
argv[1] will be a file name that you put on the command line and argc will = 2. You can strcpy argv[1] to a string with a better name, like filename.

PS. If the path to your text file has a space in it, be sure to put quotes around it. Otherwise, it will be split at the spaces into argv[1], argv[2], etc.

PPS. The path to the file name will either be relative to where your command terminal is open or absolute. It is NOT relative to the location of the program unless you open the command terminal in the same folder as the program.
 
Last edited:
  • Like
Likes ChrisVer

Similar threads

Replies
25
Views
2K
Replies
33
Views
2K
Replies
5
Views
3K
Replies
22
Views
3K
Replies
6
Views
2K
Replies
10
Views
2K
Back
Top