Solved

Parse values from Input file

Posted on 2008-10-11
33
267 Views
Last Modified: 2012-05-05
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
0
Comment
Question by:ExpExchHelp
  • 15
  • 10
  • 8
33 Comments
 
LVL 17

Expert Comment

by:sweetfa2
ID: 22695211
Homework?

First and foremost, if you have a variable declared "const" you cannot change it.
0
 

Author Comment

by:ExpExchHelp
ID: 22695423
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
 
LVL 17

Expert Comment

by:sweetfa2
ID: 22695463

#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
 

Author Comment

by:ExpExchHelp
ID: 22695555
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
 
LVL 17

Expert Comment

by:sweetfa2
ID: 22695564
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
 

Author Comment

by:ExpExchHelp
ID: 22696184
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
 

Author Comment

by:ExpExchHelp
ID: 22697088
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
 
LVL 17

Expert Comment

by:sweetfa2
ID: 22698491
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
 
LVL 53

Expert Comment

by:Infinity08
ID: 22700891
>> 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
 

Author Comment

by:ExpExchHelp
ID: 22702707
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
 
LVL 53

Expert Comment

by:Infinity08
ID: 22702740
>> 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
 

Author Comment

by:ExpExchHelp
ID: 22702971
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
 
LVL 53

Expert Comment

by:Infinity08
ID: 22703122
>> 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
 

Author Comment

by:ExpExchHelp
ID: 22703425
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
 

Author Comment

by:ExpExchHelp
ID: 22703953
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
 
LVL 53

Expert Comment

by:Infinity08
ID: 22704853
>> 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
How to improve team productivity

Quip adds documents, spreadsheets, and tasklists to your Slack experience
- Elevate ideas to Quip docs
- Share Quip docs in Slack
- Get notified of changes to your docs
- Available on iOS/Android/Desktop/Web
- Online/Offline

 

Author Comment

by:ExpExchHelp
ID: 22706531
Infinity08:

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

EEH
0
 
LVL 53

Assisted Solution

by:Infinity08
Infinity08 earned 50 total points
ID: 22710409
>> 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
 

Author Comment

by:ExpExchHelp
ID: 22717223
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
 
LVL 17

Accepted Solution

by:
sweetfa2 earned 450 total points
ID: 22717301
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
 

Author Comment

by:ExpExchHelp
ID: 22717875
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
 
LVL 17

Assisted Solution

by:sweetfa2
sweetfa2 earned 450 total points
ID: 22717990
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
 
LVL 53

Expert Comment

by:Infinity08
ID: 22718758
>> 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
 
LVL 17

Expert Comment

by:sweetfa2
ID: 22718915
Judging by the output Infinity he has picked up my latest version of code.
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 22719219
>> 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
 
LVL 17

Expert Comment

by:sweetfa2
ID: 22719224
So how is the work situation in Belgium?
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 22719241
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
 

Author Comment

by:ExpExchHelp
ID: 22719576
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
 
LVL 53

Expert Comment

by:Infinity08
ID: 22719606
That code doesn't generate any output - how do you verify that the values are read incorrectly ?
0
 

Author Comment

by:ExpExchHelp
ID: 22724039
>> 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
 

Author Comment

by:ExpExchHelp
ID: 22724348
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
 

Author Closing Comment

by:ExpExchHelp
ID: 31505349
Pls see final my final comment.
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 22724664
>> 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

Featured Post

Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

Join & Write a Comment

Many modern programming languages support the concept of a property -- a class member that combines characteristics of both a data member and a method.  These are sometimes called "smart fields" because you can add logic that is applied automaticall…
Windows programmers of the C/C++ variety, how many of you realise that since Window 9x Microsoft has been lying to you about what constitutes Unicode (http://en.wikipedia.org/wiki/Unicode)? They will have you believe that Unicode requires you to use…
Video by: Grant
The goal of this video is to provide viewers with basic examples to understand and use for-loops in the C programming language.
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.

747 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

15 Experts available now in Live!

Get 1:1 Help Now