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

In summary: I would create a folder in the same directory as the code, and put my data.txt inside it. Then I could use argc as the first parameter to the main() function, and argstr would contain the full path to the data.txt file.In summary, you can use a non-default path for the data.txt file by creating a folder in the same directory as the code and putting the data.txt inside it.
  • #1
ChrisVer
Gold Member
3,378
464
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
  • #2
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.
 
  • #3
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!
 
  • #4
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
  • #5
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
  • #6
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
  • #7
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
 
  • #8
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).
 
  • #9
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

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

1. How do I pass numbers into x and y arrays from a txt file in C++?

There are several ways to do this, but one approach is to use the std::ifstream class to read in the numbers from the txt file and then use a loop to add them to the arrays.

2. Can I use a different file format instead of txt for my data?

Yes, you can use other file formats such as CSV or JSON. However, the code to read in the numbers may be slightly different depending on the format.

3. How do I handle errors if the txt file does not contain the expected number of values?

You can use the std::getline function to read in each line of the file and then check the number of values on each line before adding them to the arrays. If the number of values is not what you expect, you can handle the error by either skipping that line or terminating the program.

4. Is it possible to pass numbers into multidimensional arrays from a txt file?

Yes, you can pass numbers into multidimensional arrays by reading in the values from the txt file and then using nested loops to add them to the correct indices in the arrays.

5. Can I use the same approach to pass strings into arrays from a txt file?

Yes, you can use a similar approach to pass strings into arrays from a txt file. Instead of using the std::ifstream class, you can use the std::stringstream class to read in the strings, and then use a loop to add them to the arrays.

Similar threads

  • Programming and Computer Science
Replies
33
Views
2K
  • Programming and Computer Science
Replies
6
Views
9K
  • Programming and Computer Science
Replies
25
Views
2K
  • Programming and Computer Science
Replies
20
Views
1K
  • Programming and Computer Science
Replies
12
Views
1K
  • Programming and Computer Science
Replies
23
Views
1K
  • Programming and Computer Science
2
Replies
65
Views
5K
  • Programming and Computer Science
Replies
5
Views
2K
  • Programming and Computer Science
Replies
32
Views
2K
  • Programming and Computer Science
Replies
1
Views
1K
Back
Top