Hi everyone,

I have a 2d array whith 50000 lines and 14 columns, and I have to sum/multiply each value of a column for a fixes numbers, like this:

a[1][14] = 0 a[1][14] + 2 = 2
a[2][14] = 2 a[2][14] + 2 = 4
a[3][14] = 5 a[3][14] + 2 = 7

How I do this for all the numbers?

I do this:

float data3 = 0;
 float data4 = 0; 
 
 
 data3 = data[1][1] + 2;
 data4 = data[2][1] + 2; 
  
 cout << data3 << "" << endl;
 cout << data4 << "" << endl;

And I like to put the values into an another 2d array with "n" lines and 1 column.

Than I have to find the maxValue of this 2d array with 1 column.

Can you help me?

Thanks

Recommended Answers

All 43 Replies

So you want to read in 50000x14 values and add a constant value to them? What do you want to do with them after that? I presume that you don't want to just print them to the console?

Do you have any more detailed example of the actual code that you've written? The code you posted above doesn't seem like it is your actual code.

hi there, i want to pick up a column of this file, and make mathematics operations, is for correction...

my is:

#include <iostream>
#include <fstream>
#include <string>
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <sstream>
using namespace std;
  
float data[200000][14]={{0.00}};

int main () {
  std::string line;
  std::ifstream is;
  float num,num1;
  std::cout << "Enter the name of an existing text file: ";
  std::getline(std::cin, line);
  is.open (line.c_str());        // open file
  if(!is.good())
    {
         cout << "openfail "; return 0;
    }

  int count=0;
  while (is.good())     // loop while extraction from file is possible
  {
     string str;
     getline (is,str);
     
     // tokenizing
     stringstream s(str);               // make string stream
     int i=0;
     // read up to 14 data elements from stringstream while stream is good (no errors)
     while(i<14 && s.good())
         {
         s >> data[count][i];
         if(!s.fail())i++ ;
         }
     if(i != 0) count++;                // increment array index
  }

  is.close();           // close file
  // print the resultant array
 
 int i = 0;
 if (i=14)
 {
          for(int j=0; j<=count; j++)
          {
          float data14[count][1];
          float data3 = 0;
          float data4 = 0; 
 
          data14[count][1] = data[i][j];
          data3 = data[1][1] + 2;
          data4 = data[2][1] + 2; 
 
          cout << data14 << "" << endl; 
          cout << data3 << "" << endl;
          cout << data4 << "" << endl; 
         }
}   
  cin.get();
  return 0;
}

i triyng to get a single column.

OK, just to mention before getting to the actual problem, there are a number of likely problems in the first few lines:

#include <iostream>
#include <fstream>
#include <string>
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <sstream>
using namespace std;
 
float data[200000][14]={{0.00}};
  1. You probably don't need #include <stdio.h> , and if you do, you should use #include <cstdio> .
  2. conio.h is not a portable header file, I think it is for use in an old Borland compiler (Turbo C, probably). IF you need it to use this compiler, then OK, but just remember that you can't use conio.h in many other compilers, so don't rely on it.
  3. You've gone for using namespace std; , which is OK in a small project but you've also used things like std::string or std::cin . These make the using statement redundant. Personally, I prefer to just use the full scope of things, like you have, but in this case you can get rid of the using statement.
  4. data is declared as a global variable for no good reason. You should declare it inside main() .
  5. You've declared an enormous array on the stack ( float data[200000][14]={{0.0}}; ). Does the program run at all, or just seg fault straight away? For arrays of this size, use new to allocate memory dynamically.

The bit of the code where you read the file seems like it should do roughly what you want, although it's probably not exactly how I'd do it.

The main issues seem to be at the end, in this bit:

int i = 0;
 if (i=14)
 {
          for(int j=0; j<=count; j++)
          {
          float data14[count][1];
          float data3 = 0;
          float data4 = 0; 
 
          data14[count][1] = data[i][j];
          data3 = data[1][1] + 2;
          data4 = data[2][1] + 2; 
 
          cout << data14 << "" << endl; 
          cout << data3 << "" << endl;
          cout << data4 << "" << endl; 
         }
}

On line 2 (above), you probably mean if(i == 14) , but actually you set int i = 0; on the line before and then don't change i , so this will always be true. I think that you might actually want something like

for(unsigned i = 0; i < 14; ++i){
    // do things here.
}

On line 6, you don't need data14[count][1] you can use a "one-dimensional" array here (although it should be declared using new as I mentioned above. On line 10, do you mean data14[j][1] = data[j][i]; , instead of data14[count][1] = data[i][j]; . What you have will (a) only write values to one element of data14 and (b) access the rows and columns of data the wrong way around. The lines for data3 and data4 are valid, but I'm not sure they're what you want. I'm still not clear what you're trying to achieve with this program. If you're just adding 2 to all of the elements, you can do it when you're reading them in, like this:

while(i<14 && s.good()){
    s >> data[count][i];
    data[count][i] += 2;    // add to the value here.
    if(!s.fail()) i++;
}

Or, if you want to, say sum all the values in a row for all the rows, then:

double *sumValues = new double[totalRows];
for(unsigned row = 0; row < totalRows; ++row){
    sumValues[row] = 0;
    for(unsigned col = 0; col < totalCols; ++col)
        sumValue[row] += data[row][col];
}

Finally, you can't print out an array like this:

cout << data14 << "" << endl;

You have to loop through all the values in the array and print each individually. The name of the array (say, data14 in this case) is just contains the address of the first element of the array.

I hope that's some help. Good luck.

Hey, thanks for the help, I correct the errors you aponted... But I think you don't undestand what I really wan't, I do a code that work, this is it:

int i = 0;
 if (i=14)
 {
          for(int j=0; j<=count; j++)
          {
          float data14[count][1];
           
          data14[count][1] = data[j][i] + 2;
           
          cout << data14[count][1] << "" << endl; 
          }
}

With this code i getch the column 14 of my 2d array and sum 2 in each value.Gerating another array with this values.

But now i have another question:

My original file, that a open and transform into this array(look at the code) have several "scans", this "scans" starts always with "#S N", where N is a number(0,1,etc)
how i make the program read the file from a determinadet scan writed, i tring do to like this:

std::cout << "Enter the number of the scan(#S Number):";
  std::getline(std::cin, line2);
  is.open (line.c_str());        // open file
  if(!is.good())
    {
         cout << "openfail "; return 0;
         cin.get();
    }
    
  int count=0;
  while (is.good())     // loop while extraction from file is possible
  {     
          string str;
          getline (is,str);
          
          int find = str.find_first_of(line2);
          if (find != 0)
          {
          // tokenizing

you can help me?

int i = 0;
 if (i=14)
 {
          for(int j=0; j<=count; j++)
          {
          float data14[count][1];
           
          data14[count][1] = data[j][i] + 2;
           
          cout << data14[count][1] << "" << endl; 
          }
}

With this code i getch the column 14 of my 2d array and sum 2 in each value.Gerating another array with this values.

Well, this code does sort of do that, but not quite. The if statement on line 2 is kind of pointless. What you're saying there is "if the value of 14 is successfully assigned to i then do the following..." You might as well loose the whole if statement and just do int i = 14; at the top. Also, you still have

float data14[count][1];
data14[count][1] = data[j][i] + 2;

which means that every time you go through the loop (and you said that count is something like 50,000) then you create an array (on the stack!) with 50000 elements and then assign the value of data[j][i] to the element past the final element of data14 ! This is (a) going to cause you a problem at some point because the biggest index that is in data14 is count - 1 and (b) very slow and wasteful. Also, when the loop exits, you will have lost all the values that you calculated, is this what you want? (and you still have float data14[count][1]; , which really doesn't serve any purpose, you should just use float data14[count]; (with the obvious caveat that you shouldn't be declaring an array like this on the stack anyway).

But now i have another question:

My original file, that a open and transform into this array(look at the code) have several "scans", this "scans" starts always with "#S N", where N is a number(0,1,etc)
how i make the program read the file from a determinadet scan writed

The code that you posted should be pretty much doing the job, the only thing that might cause a problem is the if(find != 0) . You should use if(find != std::string::npos) instead.

Other than that, I can't see anything that you couldn't figure out from here.

hi again, I don't undestand the array question, i do like that because I take the array gerated and put then into a text file.

About the second code isn't work, once I wanna to read the text file from the first match with the "scan number", gerating a minor array, with the thing that I really wan't to manipulate(once that i getch the all file).

OK, so my understanding is that you want to do the following:

  1. Read in the data, which has 14 columns and some (large) number of rows.
  2. Take column 14 and add 2 to all the values.
  3. Allow the user to select one of the rows to print to file/console/another array

Is that about right?

Could you also give one or two sample lines from your input file?

Also you said that the code you provided for finding the correct line doesn't work, what goes wrong? Are there any errors?

Ok ravenous,thanks for the help. This is fragments of my file:

"First Scan"(This is not on the file)

#S 1  a2scan  tth 25 150  th 12.5 75  12500 1
#D Mon Jan 24 15:01:42 2011
#T 1  (Seconds)
#G0 0 0 0 0 0 1 0 0 0 0 0 0 50 0 0.1 0 68 68 50 -1 1 1 3.13542 3.13542 0 463.6 838.8
#G1 5.65685 5.65685 5.65685 90 90 90 1.110721569 1.110721569 1.110721569 90 90 90 1 0 0 0 1 0 60 30 0 0 0 0 60 30 0 -90 0 0 1.54 1.54
#G2 0
#Q -1.33671 1.33671 0
#P0 30 0 0 -120 9.1812 9187 0.31351478 7937
#P1 0.063143844 0.06352646 -0.018692222 9.2878147 36.434993 14.300337 -1.7305889 0
#P2 0 -13.124 -25.8506 0 0 
#N 15
#L Two_Theta  Theta  H  K  L  Epoch  Seconds  IC1  IC2  Det2  Det3  Det4  Det5  Monitor  Detector
25 12.5 -0.790427 1.36906 0 241 1 426223 3248 11 68 13 21 474 72
25.01 12.505 -0.790738 1.3696 0 242 1 426110 3250 12 76 7 11 478 49
25.02 12.51 -0.791049 1.37014 0 243 1 426080 3247 15 87 8 11 459 59
25.03 12.515 -0.791361 1.37068 0 244 1 426048 3247 10 69 12 14 468 66
25.04 12.52 -0.791672 1.37122 0 246 1 426002 3246 19 63 9 14 502 58
...
...

"Second Scan"(This is not on the file)

#S 2  ascan  tth -0.5 0.5  50 0.1
#D Mon Jan 24 19:48:08 2011
#T 0.1  (Seconds)
#G0 0 0 0 0 0 1 0 0 0 0 0 0 50 0 0.1 0 68 68 50 -1 1 1 3.13542 3.13542 0 463.6 838.8
#G1 5.65685 5.65685 5.65685 90 90 90 1.110721569 1.110721569 1.110721569 90 90 90 1 0 0 0 1 0 60 30 0 0 0 0 60 30 0 -90 0 0 1.54 1.54
#G2 0
#Q 0 0 0
#P0 0 0 0 -120 9.1812 9187 0.31351478 7937
#P1 0.063143844 0.06352646 -0.018692222 9.2878147 36.434993 14.300337 -1.7305889 0
#P2 0 -13.124 -25.8506 0 0 
#N 14
#L Two_Theta  H  K  L  Epoch  Seconds  IC1  IC2  Det2  Det3  Det4  Det5  Monitor  Detector
-0.5 0.015814 -0.0276688 0 17364 0.1 99531 324 0 0 0 0 1818 0
-0.48 0.0151861 -0.0265594 0 17364 0.1 99534 324 0 0 0 0 1775 0
...
...

And this is what i wanna to do:

FIRST PASS:

1. Actually my program is reading all the input file.
2. I wanna to make the program read from a writed value by the user (like "#S N", where N is a number, this is the nunber of the scan) to the end of file.
3. Then make all the stringstream/operations/etc.

SECOND PASS:

1 . Read in the data, which has 14 columns and some (large) number of rows.
2 . Take column 14(or another) and find the max value of this array, put this value in a normalization variable.

THIRD PASS:

1 . Take column 13(or another) and add the normalization variable to all the values.
3 . Getch all the values yet been sum an put into another array.

The second and the third pass I want to make this 5 times with 5 columns separated.

FOURTH PASS:

1. Getch the arrays modifieds and replace then on the originals arrays.
2. Output the file i've read with this modifieds arrays.

Is a poor long, but that is it, thanks!

OK, it seems like you're working on an actual data analysis problem and not an exercise in a computer science course, so you are free to use whatever elements of C++ you like. Correct?

In this case, I would recommend using std::vector instead of dealing with C-style arrays. This will simplify your code and help reduce errors. It should be noted that std::vector isn't suitable for everything though, sometimes an array is better. You can find out more about std::vector here. To use std::vector you need to include the header <vector> , like this:

#include <iostream>
#include <vector>

int main(){
    /* create a vector of 50000 doubles and set all the elements to zero */
    std::vector< double > vec1(50000,0);

    /* you can use the [] notation as you would in an array */
    std::cout << vec1[10] << std::endl;

    return 0;
}

std::vector is dynamically resizable, so you don't have to worry about making it big enough to hold all your data up front, which also simplifies things. You can also make a "vector of vectors" (which you might use to store your data):

std::vector< std::vector < double > > data;

So, to your file. I would recommend that you take a different approach. I don't think that you need to pass the file so many times to do what you want to do. The first thing you need to do is find the right block of scan data in your file, so find the line beginning with #S n , where n is the number you're looking for. So, you don't need to read in all the scans in, just the one with the right number. I would use getline() to go through the file until I got to a line that is likely to have a scan number on it, so something like:

std::string lineFromFile;
bool found_target_scan = false;

/* Go through the whole file */
while(inputFile.fail() != true){
    /* Get a line */
    getline(inputFile,lineFromFile);

    /* Check that it's even big enough to contain what we want */
    if(lineFromFile.size() >= 4){
        /* Check that it starts with the right key */
        if(lineFromFile.substr(0,2) == '#S'){
            /* now tokenize this line and get the actual scan number out */
            /*    INSERT TOKENIZING CODE HERE ...                        */

            /* We're at the right part of the file, so set the flag to say we found the right scan and then quit */
            if(currentScanNumber == targetScanNumber){
                found_target_scan = true;
                break;
            }
        }
    }
}

/* Check that we found any scan with the right number, quit if not */
if(found_target_scan == false){
    std::cerr << "Error, unable to find scan " << targetScanNumber << ". Exiting." << std::endl;
    return 1;
}

/* Now read in the actual data ... */

From your example files it looks like there are 12 lines between the #S line and the start of the data. If this is always going to be the case, you can just skip over them with

for(unsigned i = 0; i < 12; ++i) getline(inputFile, lineFromFile);

otherwise you will have to use another while loop to look for the line starting #L and then just start on the following line.

To read in the data, use the method std::vector::push_back() :

std::vector< std::vector< double > > data;     // A vector of vectors for the data
std::vector< double > dataLine(14);            // A temporary vector that just stores 1 line of data

/Go through the file */
while(inputFile.fail() != true){
    /* Get a line */
    getline(inputFile, lineFromFile);
    
    /* Check that the line has something on it */
    if(lineFromFile.size() > 0){
        /* Make a string stream for tokenizing */
        std::stringstream inStream(lineFromFile);
        unsigned i = 0;
        
       /* Try and split the line into 14 chunks */
        while(i < 14 && inStream.good()){
            /* Store the value of each chunk in the temp. vector */
            inStream >> dataLine[i];
            ++i;
        }
        
        /* Check to see if there's the right number of parts to the line */
        if(i == 13)
            data.push_back(dataLine);          // Add this line of data to the rest if there is
        else                                   // else, quit since something's wrong
            break;
    }
    else{       // If there's no data on the line, quit (it's probably the end of the data)
        break;
    }
}

So now all the data from the scan of interest should be in the data matrix (a vector of vectors can be a bit like a matrix, and it's quicker to say!). You can access the data by doing

data[rowNumber][columnNumber];

as you previously have for your arrays. All the other operations that you describe can be done with the methods described above (making vectors and vectors of vectors, inserting data and accessing and changing elements).

To write the resulting matrices to file, you need to create an output file stream and loop through all the rows and columns of you matrix, like:

std::ofstream outFile("out.txt");

for(unsigned row = 0; row < data.size(); ++row){
    for(unsigned col = 0; col < data[row].size(); ++col)
        outFile << data[row][col] << ' ';
    outFile << '\n';
}
outFile.close();

That should be about it. I would also recommend getting a good C++ book. I liked Deitel & Deitel's "C++ How to Program" (here), but you have to find what works for you.

Dear Lord! Ravenous you are the best! Man, i understand everything, but my aknowledge about the specific language don't let me to make this program run!

I understand the use of the vector, once they are redimensionable, your logical is perfect the conditions to make the read and all the another things, but I don't make this program run, sorry, I don't wanna to look that I'm asking to you do all the job, but you can put all that codes you pass together to make run?

The conditions to make run, and the operations with the columns I will do, your help very nice!

Thanks for the the time wasted! But waste a little more? Haha!

I don't wanna to look that I'm asking to you do all the job, but you can put all that codes you pass together to make run?

Sorry, can't do that. I don't have a working program anyway, I just typed the parts on the post straight into Daniweb.

There's a saying:
"Give a man a fish and he will have food for a day, teach a man to fish and he will have food forever"

So, when you say that there are errors, what do you mean? Can you compile your program? If not, what errors does the compiler give? If you run it, but it runs forever, or stops because of an error (like a segmentation fault) then at what point does the error occur? Or maybe it runs without error, but gives the wrong answers?

You can find out where an error is occurring by using a debugger, or if it is something simple, then you can put statements in your code that print the values of variables to the console. For example, if I have a program like this:

#include <iostream>

int main(){
    unsigned n = 10000;
    double array[10];
    for(unsigned i = 0; i < 10; ++i)
        array[i] = i;
    
    for(unsigned i = 0; i < n; ++i)
        array[i] += 10;
    
    for(unsigned i = 0; i < 10; ++i)
        std::cout << array[i] << ' ';
    std::cout << std::endl;

    return 0;
}

This will compile fine, but will cause an error when run. To find the error, you could put a statement like std::cerr << "got to line " << __LINE__ << std::endl; at various points in the file, like this:

#include <iostream>

int main(){
    unsigned n = 10000;
    double array[10];

    std::cerr << "got to line " << __LINE__ << std::endl;

    for(unsigned i = 0; i < 10; ++i)
        array[i] = i;
    
    std::cerr << "got to line " << __LINE__ << std::endl;

    for(unsigned i = 0; i < n; ++i)
        array[i] += 10;
    
    std::cerr << "got to line " << __LINE__ << std::endl;
   
    for(unsigned i = 0; i < 10; ++i)
        std::cout << array[i] << ' ';
    std::cout << std::endl;

    std::cerr << "got to line " << __LINE__ << std::endl;

    return 0;
}

__LINE__ tells the compiler to put the line number of the source code where it sees __LINE__ . In this case, the output of the program should be something like

got to line 7
got to line 12
segmentation fault

So we know that the problem is between lines 12 and 17. So it must be the loop. To investigate the loop, you might look at what values the loop variable ( i in this case) is taking, so you might change the program to be something like

#include <iostream>

int main(){
    unsigned n = 10000;
    double array[10];
    for(unsigned i = 0; i < 10; ++i)
        array[i] = i;
    
    for(unsigned i = 0; i < n; ++i){
        std::cerr << "in loop, i = " << i << std::endl;
        array[i] += 10;
    }
    
    for(unsigned i = 0; i < 10; ++i)
        std::cout << array[i] << ' ';
    std::cout << std::endl;

    return 0;
}

So now when the program is run, the output appears like this:

in loop, i = 0
in loop, i = 1
in loop, i = 2
in loop, i = 3
in loop, i = 4
in loop, i = 5
in loop, i = 6
in loop, i = 7
in loop, i = 8
in loop, i = 9
in loop, i = 10
segmentation fault

So now we can see that the problem is that we are trying to access the 11th element of array , which is not good and the OS stops the program.

By doing this (or, even better using breakpoints in a debugger to do the same thing) you can find the bits of the code that are causing the problems, and have more chance of fixing them. You can obviously print out the values of other things too, like values that you're reading to file, or passing to functions etc. When you can say exactly what is causing the problem, then we can help you fix it. It's quite likely that by the time you've isolated it in the way that I just described, you'll have figured it out for yourself though :)

Really try and think about what assumptions you're making and what each bit of code is doing and you'll figure it out. The good thing about programming is that (in principle) you have access to every detail of the system - all the information is there, so it's always possible to figure it out in the end. Patience is a requirement for programming.

commented: Very helpful +6

Thanks man, i know that i'm think about it, and i'm think, realy, last 2 weeks i only do this!

ok, i tried do make the program run:

the is this:

#include <iostream>
#include <vector>
#include <fstream>
#include <string>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <sstream>
using namespace std;

int main(){
    std::string line; 
    std::string lineFromFile;
    std::string targetScanNumber; 
    std::ifstream inputFile;
    std::cout << "Enter the name of an existing text file: ";
    std::getline(std::cin, line);
    inputFile.open (line.c_str()); 
    std::cout << "Enter the number of the scan:";
    std::getline(std::cin, targetScanNumber);

    bool found_target_scan = false;

    /* Go through the whole file */
    while(inputFile.fail() != true){
    /* Get a line */
    getline(inputFile,lineFromFile);

    /* Check that it's even big enough to contain what we want */
    if(lineFromFile.size() >= 5){
        /* Check that it starts with the right key */
        if(lineFromFile.substr(0,2) == "#S"){
            /* now tokenize this line and get the actual scan number out */
            /*    INSERT TOKENIZING CODE HERE ...                        */
            string currentScanNumber;
            stringstream h(lineFromFile);
            h >> currentScanNumber;           
  
                  /* We're at the right part of the file, so set the flag to say we found the right scan and then quit */
                  if(currentScanNumber == targetScanNumber){
                  found_target_scan = true;
                  break;
            }
        }
    }
}

/* Check that we found any scan with the right number, quit if not */
if(found_target_scan == false){
    std::cerr << "Error, unable to find scan " << targetScanNumber << ". Exiting." << std::endl;
    cin.get();
    return 1;
}

    /* Now read in the actual data ... */
    std::vector< std::vector< double > > data;     // A vector of vectors for the data
                  std::vector< double > dataLine(14);            // A temporary vector that just stores 1 line of data

                  /*Go through the file */
                  while(inputFile.fail() != true){
                       /* Get a line */
                       getline(inputFile, lineFromFile);
    
                       /* Check that the line has something on it */
                       if(lineFromFile.size() > 0){
                          /* Make a string stream for tokenizing */
                          std::stringstream inStream(lineFromFile);
                          unsigned i = 0;
        
                          /* Try and split the line into 14 chunks */
                          while(i < 14 && inStream.good()){
                                  /* Store the value of each chunk in the temp. vector */
                                  inStream >> dataLine[i];
                                  ++i;
                                  }
        
                         /* Check to see if there's the right number of parts to the line */
                         if(i == 13)
                         data.push_back(dataLine);          // Add this line of data to the rest if there is
                         else                                   // else, quit since something's wrong
                         break;
                         }
    else{       // If there's no data on the line, quit (it's probably the end of the data)
        break;
    }
}
    cin.get();
    return 0;
}

I'm havin trouble in the "INSERT TOKENIZING CODE HERE" the program is running, but always it shows:

Enter the name of file: (I put the name /enter)
Enter the number os the scan: 1 (for example, or any another number)
(Then it make the error message) "Error, unable to find scan .exiting."

any help?

about that book, you have any file of then? because i'm brazilian guy, and buy they is hard!

(Then it make the error message) "Error, unable to find scan .exiting."

So, if you look at the line of code that generates this message:

std::cerr << "Error, unable to find scan " << targetScanNumber << ". Exiting." << std::endl;

If everything was working correctly, and you tell it to look for scan 1, then the error message should say: Error, unable to find scan 1. Exiting. but it doesn't, the "1" is missing. What does that tell you?

about that book, you have any file of then? because i'm brazilian guy, and buy they is hard!

That was just an example. There are many good books on C++. Best to find one that is available locally, or from an onlie seller that covers your region.

Also, have you tried printing out the value of currentScanNumber after you do h >> currentScanNumber . That kind of information is always useful :)

It print #S#S#S#S#S#S#S#S, and the number I'v digited is apearing "Error, unable to find scan n. Exiting."

It print #S#S#S#S#S#S#S#S, and the number I'v digited is apearing "Error, unable to find scan n. Exiting."

So, why do you think it's printing "#S#S#S#S#S#S#S#S"? In your file you have something like

#S 3 ...some other bits

You search for the #S at the start of the line. When you find it you take the line and do

h >> lineFromFile;

which gives you #S . The number is the next token along from #S , so to get the number you'd have to...?

i have to "jump" the #S and go to the next position, that will be (0,3), ok? But how i do this?

i have to "jump" the #S and go to the next position, that will be (0,3), ok? But how i do this?

There are two ways, you could just repeat the stream extraction line:

string currentScanNumber;
stringstream h(lineFromFile);
h >> currentScanNumber;     // Gets the "#S" part that we don't want
h >> currentScanNumber;     // Gets the actual number!      
 
/* We're at the right part of the file, so set the flag to say we found the right scan and then quit */
if(currentScanNumber == targetScanNumber){
    found_target_scan = true;
    break;
}

Or, you could use the std::string::substr() method of lineFromFile to only pass h the relevant part of the string:

string currentScanNumber;
/* use std::string::substr() to miss the #S at the start of lineFromFile */
stringstream h(lineFromFile.substr(2));
h >> currentScanNumber;   
 
/* We're at the right part of the file, so set the flag to say we found the right scan and then quit */
if(currentScanNumber == targetScanNumber){
    found_target_scan = true;
    break;
}

You can read more about substr() here

ok, but the stringstream is not working, since i print "h" and gave = "0x22.."

ok, but the stringstream is not working, since i print "h" and gave = "0x22.."

If you have

std::cout << h << std::endl;

then you will get something that looks like 0xbfb9a454 or some other number, this is the memory address of the string stream. You can't really get anything useful by doing that. You should print out the currentScanNumber after you think you've read it in, like this:

std::stringstream h(lineFromFile);

h >> currentScanNumber;
h >> currentScanNumber;

std::cout << "currentScanNumber = " << currentScanNumber << std::endl;

ahh ok, sorry my dummy, i put that and gerate this:

if i digited 4 in scan number

currentScanNumber = 1
currentScanNumber = 2
currentScanNumber = 3
currentScanNumber = 4

??

oooh! i test the another cout, and now, the program take all the data until the digited scan

ok ok, i see what hapeneed, but how i do to start the reading from that scan until another? thanks a lot

oooh! i test the another cout, and now, the program take all the data until the digited scan

Excellent, so it gets to the scan number that you want.

Now you just need to add some code to make it move over the lines that start '#D', '#G', etc. until you get to the actual data that you want to read. I mentioned some ways to do that previously (either just move down 12 lines, or look for the next line that starts '#L').

I hope that has helped a bit.

ok ok, but this is not doing what I want, they read all the data until the digited scan. I wanna to read starting in the digited scan, until another scan(for this i'm making a condition(if substring = "#")).

Why they read until the digited scan?

ok ok, but this is not doing what I want, they read all the data until the digited scan. I wanna to read starting in the digited scan, until another scan(for this i'm making a condition(if substring = "#")).

Why they read until the digited scan?

Look at the code, it's not actually storing any of the data, it's just examining the start of each line until it finds one that begins with '#S'. When it finds one of these lines it looks at the number. If it's the right number it should break out of the while loop. If it's not the right number it should keep going.

If you are using the program that you posted previously, then you won't get it to work properly until you make some code to move past the rest of the lines between the '#S' line and the start of the numbers that you want to read in.

If you examine the code for reading the data you will see that there are a number of conditions that will cause it to break out of the while loop and stop reading the data. The loop for reading that data looks like this:

while(inputFile.fail() != true){
    /* Get a line */
    getline(inputFile, lineFromFile);
 
    /* Check that the line has something on it */
    if(lineFromFile.size() > 0){
        /* Make a string stream for tokenizing */
        std::stringstream inStream(lineFromFile);
        unsigned i = 0;
 
       /* Try and split the line into 14 pieces of data */
        while(i < 14 && inStream.good()){
            /* Store the value of each chunk in the temporary vector */
            inStream >> dataLine[i];
            ++i;          // Keep a count of how many parts we've found
        }
 
        /* Check to see if there's the right number of parts to the line */
        if(i == 13)
            data.push_back(dataLine);          // Add this line of data to the rest if there is
        else                                   // else, stop reading as it looks like something's wrong
            break;
    }
    else{       // If there's no data on the line, quit (it's probably the end of the data)
        break;
    }
}

Take a look at this code and read the comments in it, you can see that the program will go through the data until it comes to a line that looks like it doesn't have any data on it (either it's empty, of there are not enough pieces of data to be a full line). It will then stop reading data and break out of the while loop.

Hi ravenous, me again =]!

My program was working, but i do something and don't work anymore, before i put the scan number and then it find the scan and stop, now it gerates a loop of "current scan number", like this:

current scan number 1
current scan number 2
current scan number 3
current scan number 4
current scan number 5
...
current scan number 21(my number of scans in file)

I'm stocked in this since yearsterday, I'm change various variables and don't make any effect!

And is another problem, the program isn't read the data after discover the right scan!

My code is that:

#include <iostream>
#include <vector>
#include <fstream>
#include <string>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <sstream>
using namespace std;

int main(){
    //declarate variables
    std::string line; 
    std::string lineFromFile;
    std::string lineFromFile2;
    std::string targetScanNumber; 
    std::ifstream inputFile;
    //read the name of the file
    std::cout << "Enter the name of an existing text file: ";
    std::getline(std::cin, line);
    inputFile.open (line.c_str()); //open the file
    if (inputFile.good())
    {
    //get the number of the scan
    std::cout << "Enter the number of the scan:";
    std::getline(std::cin, targetScanNumber);
    }
    else
    {
    cout << "Can't read the file" << endl;
    }
    //std::cout << targetScanNumber << "" << endl;
    
    //set flag for target scan false
    bool found_target_scan = false;
    

//-------------------------------------READ FILE/SCAN---------------------------------------//
  while(inputFile.fail() != true) /* Go through the whole file */
  {
    getline(inputFile,lineFromFile);/* Get a line */
    //cout << lineFromFile << "" << endl;
    if(lineFromFile.size() >= 4)/* Check that it's even big enough to contain what we want */
    {
        if(lineFromFile.substr(0,2) == "#S")/* Check that it starts with the right key */
        {
          std::string currentScanNumber;  //tokenize line//
          std::stringstream h(lineFromFile);

          h >> currentScanNumber;
          h >> currentScanNumber;
          
          //std::cout << "targetScanNumber = " << targetScanNumber << std::endl; 
          std::cout << "currentScanNumber = " << currentScanNumber << std::endl;         
  
  
          if(currentScanNumber == targetScanNumber)/* We're at the right part of the file, so set the flag to say we found the right scan and then quit */
               {
               found_target_scan = true;
               }
        }//if sub
    }//if size
  }//while imput
  


// --------------------------------------READ DATA-------------------------------------------------------------//
std::vector< std::vector< double > > data;     // A vector of vectors for the data
std::vector< double > dataLine(14);            // A temporary vector that just stores 1 line of data

while(inputFile.fail() != true && found_target_scan == true )/*Go through the file */
{
 getline(inputFile, lineFromFile2);/* Get a line */
 std::cout << lineFromFile2  << "" << endl;
    
 if(lineFromFile2.size() > 0) /* Check that the line has something on it */
             {
                  std::stringstream inStream(lineFromFile); /* Make a string stream for tokenizing */
                  std::cout << inStream << "" << endl;
                          
                  unsigned i = 0;
           
                  while(i < 14 && inStream.good()) /* Try and split the line into 14 chunks */
                     {                                  
                     inStream >> dataLine[i];  /* Store the value of each chunk in the temp. vector */                                  
                     std::cout << dataLine[i] << "" << endl;
                     ++i;
                     }//while i             
                  if(i == 13)/* Check to see if there's the right number of parts to the line */
                  { 
                  data.push_back(dataLine);// Add this line of data to the rest if there is
                  }         
                  else                                   // else, quit since something's wrong
                  break;
             }//ifsize                          
             else   // If there's no data on the line, quit (it's probably the end of the data)
             {       
             break;
             }
           //for
         }//while fail

std::ofstream outFile("out.txt");

for(unsigned row = 0; row < data.size(); ++row){
    for(unsigned col = 0; col < data[row].size(); ++col)
        outFile << data[row][col] << ' ';
    outFile << '\n';
}
outFile.close();


    cin.get();
    return 0;
}

Any help?

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.