Parse values from Input file

Currently, I have 2 variables (ROWS and COLS) hardcoded in my C/C++ program.    These two variables are:
const int COLS = 125;
const int ROWS = 100;

Instead of hardcoding them, I'd like to dynamically read them from an input file instead.   So, the pseudo process should be:
1. const int COLS = 0;
2. const int ROWS = 0;
3. Open "data_input_file.hdr" (see attached)
4. Read first two lines of the header files
5. Now set the following: const int COLS= 125;               // where header file's ncols = COLS
6. and set const int ROWS = 100;                                     // where header file's nrows = ROWS
7. Close "data_input_file.hdr"                    ... or something like this

Note:  For file uploading purposes into EE, I had to change the extension from ".hdr" to ".txt".

How do I do this?  Pls provide specific C/C++ code?

Thank you!
EEH
data-input-file.txt
ExpExchHelpAsked:
Who is Participating?

Improve company productivity with a Business Account.Sign Up

x
 
sweetfa2Connect With a Mentor Commented:
Have a look at the lines marked // sweetfa.  They are the ones you need to change in your program.  Please try and figure out why I made the changes.
/*
 * ss.cpp
 *
 *  Created on: 15/10/2008
 *      Author: frank
 */
 
// reading a text file
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>	// sweetfa
using namespace std;
 
 
std::string word;
int value;
//double number;
 
 
int main () {
	int nCols = 0;	// sweetfa
	int nRows = 0;	// sweetfa
  string line;
  ifstream myfile ("datafile.hdr");
  if (myfile.is_open())
  {
    while (! myfile.eof() )
    {
      getline (myfile,line);
 
          stringstream ss(line, stringstream::in);		// sweetfa
          //ss >> word >> value >> number;
          ss >> word >> value;                   // only need to get the integer value
 
          if (word == "ncols")		// sweetfa
        	  nCols = value;		// sweetfa
          if (word == "nrows")		// sweetfa
        	  nRows = value;		// sweetfa
      cout << line << ":" << word << ":" << value << endl;
    }
    myfile.close();
  }
 
  else cout << "Unable to open file";
 
  cout << "nRows = " << nRows << endl;	// sweetfa
  cout << "nCols = " << nCols << endl;	// sweetfa
  return 0;
}

Open in new window

0
 
sweetfa2Commented:
Homework?

First and foremost, if you have a variable declared "const" you cannot change it.
0
 
ExpExchHelpAuthor Commented:
Each time the program is executed, it would be a one-time "parsing"... the values would NOT have to be re-read during execution.

I simply want to be able to load any given file (dynamically) vs. hardcoding the column and row values when changing a source file.

Doable?

EEH
0
Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

 
sweetfa2Commented:

#include	<stdio.h>
#include	<assert.h>
 
 
int main(int argc, char **argv)
{
	int COLS = 0;
	int ROWS = 0;
 
	FILE *fd = fopen("data_input_file.hdr", "r");
	assert(fd);
 
	fscanf(fd, "ncols %d\nnrows %d\n", &COLS, &ROWS);
	fclose(fd);
 
	printf("New values are %d:%d\n", COLS, ROWS);
	return 0;
}

Open in new window

0
 
ExpExchHelpAuthor Commented:
Ok, the program compiles and builts successfully,

When executing though, I don't see the values being printed to the command window.  Quick follow-up questions:

1. Is there another way to check what the new current values is?
2. The variable names in my actual header file are called: "ncols" & "nrows".   The names in the C++ file are: "nCOLS" and "nROWS".    Does that upper/lower case matter?

EEH
0
 
sweetfa2Commented:
1. if the printf is not displaying in the window it must be directed to a log somewhere.  find where your program output goes to.
2. No, they are just spaceers to be ignored.

If your code has those values set as "CONST" they will never change and they will stay at zero.

Note that const means "a constant value that never changes after initialisation"
0
 
ExpExchHelpAuthor Commented:
sweetfa2:

I think I don't need to keep them as constants... I'm sure "int" will do just fine.

I don't put out their values anywhere... I need them for calculations in the program though.

Right now, the DOS console window blinks for a tiny fraction of a second.    It's goes away too fast so I don't know if it's printing those 2 values.

Is there a way to pause the console screen or how do I hover over a variable and "see" its new value?

Thanks for being patient w/ me on this...

EEH
0
 
ExpExchHelpAuthor Commented:
Quick follow-up to my previous post...

I used a batch file to include a "pause" statement:
******************************
cd ..
cd ..
cd "Documents and Settings\...\03_HeaderFile\Debug"
cls
03_HeaderFile
pause
******************************

Line 13 "assert(fd);) throws an error during the execution.   Pls see attached snapshot of the error (latest code is included below).

Any more ideas?
EEH

#include	<stdio.h>
#include	<assert.h>
 
 
int main(int argc, char **argv)
{
	int COLS = 0;
	int ROWS = 0;
 
	printf("Current values are %d:%d\n", COLS, ROWS);
 
	FILE *fd = fopen("ned_03379207.hdr", "r");
	assert(fd);
 
	fscanf(fd, "ncols %d\nnrows %d\n", &COLS, &ROWS);
	fclose(fd);
 
	printf("New values are %d:%d\n", COLS, ROWS);
	return 0;
}

Open in new window

error.jpg
0
 
sweetfa2Commented:
It cannot open the header file.  Make sure it is in the same directory as your application is running in, or change the filename to be a pathname
0
 
Infinity08Commented:
>> How do I do this?

The simple and short idea is to read the values from the file, and then use those values to dynamically allocate the memory, rather than statically.

Here's a tutorial on I/O with files in C++ :

        http://www.cplusplus.com/doc/tutorial/files.html

And here's one about dynamic memory :

        http://www.cplusplus.com/doc/tutorial/dynamic.html

After reading and understanding these two, you should be able to implement something that works for this.

Do not hesitate to ask for clarification where needed.
0
 
ExpExchHelpAuthor Commented:
Infinity08:,

I've read the information on the 2 websites... not sure if I have a full grasp of the info though.

Ok, I've started w/ the code below.   It results in "unable to open file" output.     I've attached the input data file (datafile.hdr... pls change extension from .txt to .hdr).  

Process recap:
- when I execute the program, I want to initialize the two variable COLS & ROWS with "0"
- then I want to parse their two values (473, 397)
- print out the two values (for testing purposes only)
- use those values from then on for calculation purposes

This sounds easy... but I'm having a tough time coding this.

Any suggestions?
EEH
Using the program code...
 
&&&&&&&&&
// reading a text file
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
 
int main () {
  string line;
  ifstream myfile ("datafile.hdr");
  if (myfile.is_open())
  {
    while (! myfile.eof() )
    {
      getline (myfile,line);
      cout << line << endl;
    }
    myfile.close();
  }
 
  else cout << "Unable to open file"; 
 
  return 0;
}
&&&&&&&&&

Open in new window

datafile.txt
0
 
Infinity08Commented:
>> It results in "unable to open file" output.

Did you place the input file in the same directory as the executable ?


>> - when I execute the program, I want to initialize the two variable COLS & ROWS with "0"
>> - then I want to parse their two values (473, 397)
>> - print out the two values (for testing purposes only)
>> - use those values from then on for calculation purposes

Sounds good - simple steps that you can implement :)
0
 
ExpExchHelpAuthor Commented:
Ok, I was under the impression that the datafile should reside on the same level of the CPP file... I now moved it into the Debug folder... it executes and the entire data file is displayed in the command console.

I also tried the code suggested from sweetfa2... it also prints the "0" values.

However, the problem still exist in either method:

I don't want to print the entire datafile to the command console... instead, I want to simply parse the values >> 473, 397 <<.  

How do I do that?

EEH
0
 
Infinity08Commented:
>> I don't want to print the entire datafile to the command console... instead, I want to simply parse the values >> 473, 397 <<.  

Instead of reading a line and printing it like you do now, you should read the first two lines of the data file (one at a time), and extract the COLS and ROWS values.

Once you have read a line into a string (using getline like you did), you can get the integer value from it using a stringstream for example. Suppose I have a string like this :

        std::string str = "Test 25 7.0";

with three distinct tokens in it : a word "Test", an integer value 25, and a floating point value 7.0 :

        std::string word;
        int value;
        double number;

you could then use a stringstream to get these 3 tokens out of the string into the three separate parameters :

        std::stringstream ss(str);            // <--- we put the string into the stringstream
        ss >> word >> value >> number;

The second line extracts the three tokens from the stringstream one by one (in the right order).


More info about stringstreams :

        http://www.cplusplus.com/reference/iostream/stringstream/stringstream.html

(check the code sample too)
0
 
ExpExchHelpAuthor Commented:
Wow... not sure if I totally follow this..

I'm using the code below and get plenty of compile errors.   I'm sure it's something fundamental...

Based on your example, I could parse the word, integer, and floating decimal.   I've dropped the floating decimal for right now.

Still, it's not working yet.... what am I missing or doing wrong?

EEH
// reading a text file
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
 
 
std::string word;
int value;
//double number;
 
 
int main () {
  string line;
  ifstream myfile ("datafile.hdr");
  if (myfile.is_open())
  {
    while (! myfile.eof() )
    {
      getline (myfile,line);
 
	  std::stringstream ss(str);
	  //ss >> word >> value >> number;          
	  ss >> word >> value;                   // only need to get the integer value
 
      cout << line << endl;
    }
    myfile.close();
  }
 
  else cout << "Unable to open file"; 
 
  return 0;
}

Open in new window

0
 
ExpExchHelpAuthor Commented:
Follow-up to my previous post... not sure if I made the goal entirely clear.

I don't want to include a specific string e.g. "COLS          473" in my code.   Here's why... another data file may contain "COLS          815" and so forth.

So, as you can see, I want to be able to parse any input file as long as its name is "datafile.hdr".   And each data file will have COLS as its first line and ROWS as its second line.

That'll allow me to read any file as long as the filename won't change.

EEH
0
 
Infinity08Commented:
>> Based on your example, I could parse the word, integer, and floating decimal.   I've dropped the floating decimal for right now.

What I posted was just an example. You have to first understand what it's doing and how it works, and then you can use that knowledge to parse your own data file.

You cannot use the code I posted - it will not work. You will have to write your own after understanding how it works.

You can read up on stringstreams on the web page I posted. In short, a stringstream gives access to a string as if it were a C++ I/O stream - so you can use the normal stream functionality with it.
Do you know C++ streams ?


>> not sure if I made the goal entirely clear.

More than clear ;)
0
 
ExpExchHelpAuthor Commented:
Infinity08:

still learning C/C++... just "streams" are a new territory to me.

EEH
0
 
Infinity08Connect With a Mentor Commented:
>> just "streams" are a new territory to me.

streams are the normal way of performing I/O in C++. You can see a stream as a stream of characters, coming from (or going to) some source (destination).

The standard input stream (cin) is generally connected to the keyboard where the user types his input.
The standard output stream (cout) is generally connected to the monitor where the user sees the output of the application.

Every key the user presses is put on the cin stream, so your application can read and process those characters.
All output that your code generates is similarly placed on the cout stream, which will be sent to the monitor.


Now, streams are relatively high level, so you can read/write characters from/to them, but you can also read/write integers, floating point values, strings, and even more complicated data types.
This happens simply like this :

        int value = 0;
        cin >> value;

will read an integer value from the standard input and place it in the 'value' variable.

Similarly :

        std::string word;
        cin >> word;

will read a string (one word) from the standard input and place it in the 'word' variable.

Output works the same :

        cout << word << " " << value;

will output the 'word' string to the standard output, followed by a space, and followed by the 'value' integer.


For more information, you should read up on streams, for example here :

        http://www.cplusplus.com/doc/tutorial/basic_io.html


Streams are not only used for standard I/O, but also for file I/O and even for stringstreams (giving access to a string through a stream).
0
 
ExpExchHelpAuthor Commented:
Still no luck... I don't get the values parsed out.   Didn't expect this to be a frustrating issue.   Unfortunately, it is...   8(

EEH
0
 
ExpExchHelpAuthor Commented:
sweetfa2:

thanks for the guidance on this... I appreciate it (and your patience w/ me).

Ok, I'm still printing the whole file.   I don't want that.   Also, at the end, it appears that the values for ncols and nrows are "0".

The only thing that I need to print is as follows:
473
397

... that's it... just the 2 numbers.   All else should be displayed (printing to console is only for testing purposes to make sure that 0 has changed to 473 and 0 has changed to 397, for cols and rows respectively).

Difficult?

EEH
cout.jpg
0
 
sweetfa2Connect With a Mentor Commented:
Remove line 40.  That will stop it printing the whole file.

Obviously the data file you are working with is not the same one you have posted, so ...

in line 26 change "ncols" to be "COLS"
in line 28 chante "nrows" to be "ROWS"
in line 47 remove          << "nRows = "
in line 48 remove          << "nCols = "

and you will achieve your desired output.
0
 
Infinity08Commented:
>> Still no luck... I don't get the values parsed out.

You should post your current code as well as the file you are reading in ... Otherwise, it's just guessing work for us.


But let's get back to streams first. Did you understand everything ? Or are there still parts that you have doubts about ?
I would suggest to play around a bit with streams first ... Write some simple code with them, and see if it does what you expect.
0
 
sweetfa2Commented:
Judging by the output Infinity he has picked up my latest version of code.
0
 
Infinity08Commented:
>> Judging by the output Infinity he has picked up my latest version of code.

He already had a problem before you posted that code ;) I was interested in seeing his own code, since I'm sure he was quite close to the solution.
0
 
sweetfa2Commented:
So how is the work situation in Belgium?
0
 
Infinity08Commented:
In our sector, not too much problems. There are a few companies that have to file bankruptcy due to the current "crisis", but other than that, it's business as usual :)
0
 
ExpExchHelpAuthor Commented:
sweetfa,

the 2variables (in both .cpp and .hdr) have been called "ncols" and "nrows".

The program stills generates 0s for both (at least for me).    'Wish I was as lucky as you and see the 473 and 397.    Am I still missing something here?

Below is the code and the .hdr file... to make sure we're on the same sheet of music.

Thanks,
EEH




/*
 * ss.cpp
 *
 *  Created on: 15/10/2008
 *      Author: frank
 */
 
// reading a text file
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>	// sweetfa
using namespace std;
 
 
std::string word;
int value;
//double number;
 
 
int main () {
	int ncols = 0;	// sweetfa
	int nrows = 0;	// sweetfa
  string line;
  ifstream myfile ("datafile.hdr");
  if (myfile.is_open())
  {
    while (! myfile.eof() )
    {
      getline (myfile,line);
 
          stringstream ss(line, stringstream::in);		// sweetfa
          //ss >> word >> value >> number;
          ss >> word >> value;                   // only need to get the integer value
 
          if (word == "ncols")		// sweetfa
        	  ncols = value;		// sweetfa
          if (word == "nrows")		// sweetfa
        	  nrows = value;		// sweetfa
      //cout << line << ":" << word << ":" << value << endl;
    }
    myfile.close();
  }
 
  else cout << "Unable to open file";
 
  //cout << "nrows = " << nrows << endl;	// sweetfa
  //cout << "ncols = " << ncols << endl;	// sweetfa
  return 0;
}

Open in new window

datafile.txt
0
 
Infinity08Commented:
That code doesn't generate any output - how do you verify that the values are read incorrectly ?
0
 
ExpExchHelpAuthor Commented:
>> That code doesn't generate any output - how do you verify that the values are read incorrectly ? <<

Not sure what you mean... what I meant to say is that I've verified that it's printing out the code (during testing phase), I won't print it out any longer.

Now, about this thread... it's getting too long.   I will close this thread by tomorrow.   Obviously, we're going here into philosophical discussions.  

I understand the "learning aspect" and that you dont' want to handfeed answers.    At the same time, I have NOT been able to generate the desired results.     I don't want to waste your time any longer w/ helping me.   It is obvious that you're unwilling to post the required code that I'm after.    And that's ok... I will hope that another forum will be more straight-forward.

Again, I do thank both of you for your time and willingness to teach me.   At the same time, I"m trying to solve the problem at hand.    So far, I was not able to get the help I needed to bring this to conclusion.

EEH
0
 
ExpExchHelpAuthor Commented:
sweetfa, Infinity08:

I apologize for my last comment.   The solution that sweetfa provided DOES work.

I tried it this morningn (early) at home and I only generated "0s"... I now "played" w/ this again (at work... and after a few more coffees) and I get the desired results.

So, again, I apologize for my previous comments which indicated that the solution isn't working.   Pls forgive me.

I will award 450 points to sweetfa for providing the final solution.   At the same time, for helping me w/ some learning, I'd like to also recognize Infinity08 and award some points as well.

I hope that's ok w/ both of you.

Again, thanks for being patient w/ me on this long thread.

EEH
0
 
ExpExchHelpAuthor Commented:
Pls see final my final comment.
0
 
Infinity08Commented:
>> what I meant to say is that I've verified that it's printing out the code (during testing phase), I won't print it out any longer.

If some code isn't working the way you want, then we can only help you if you show us that exact code ;) In other words, if the output is showing 0's, then we'll need to see the code that generates that output. Otherwise, all we can do is guess.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.