Reputation: 177
I am reading from a ascii file, which contains information from a picture. The file looks like
1,434,341,158,498,... until the end of a row of pixels. The next pixel row then starts below 5,316,211,323,269,... etc repeating until all pixels have been covered.
I am trying to use getline() to write these data values to an array for processing. The part of my code responsible for exacting the value is as follows:
while(!asciiimage.eof()){
string pixelvalue;
getline(asciiimage, pixelvalue, ',');
cout << pixelvalue << endl;
}
This loops until the end of the file. This works fine for one row of pixels, however at the end of the row of pixels the cout look something like this:
115
134
465
200
with a gap inbetween the values. I would like to detect this gap. I have tried to detect it using
pixelvalue.length();
pixelvalue.size();
but both of these were unsuccessful. How else can i detect this blank value of pixelvalue?
Upvotes: 0
Views: 115
Reputation: 1
Your main problem probably is the
while(!asciiimage.eof()){
condition IMHO. You can read about more of the reasoning here: Why is iostream::eof inside a loop condition considered wrong?
Here's what I would do
// Consider asciiimage is your text file input
std::istringstream asciiimage(R"input(1,434,341,158,498
5,316,211,323,269
42,508,645,232,2)input");
std::vector<std::vector<int>> pixelrows;
std::string line;
while(std::getline(asciiimage,line)) {
pixelrows.push_back(std::vector<int>());
std::istringstream linein(line);
int num;
while(linein >> num || !linein.eof()) { // << Note these different conditions
if(linein.fail()) { // just clear the streams error state, and
// consume any characters, that don't fit your
// expected formats
linein.clear();
char dummy;
linein >> dummy;
continue;
}
pixelrows.back().push_back(num);
}
}
To output/process the gathered pixel values you can do as follows then
for(auto itRow = pixelrows.begin();
itRow != pixelrows.end();
++itRow) {
for(auto itCol = itRow->begin();
itCol != itRow->end();
++itCol) {
if(itCol != itRow->begin()) {
std::cout << ", ";
}
std::cout << *itCol;
}
std::cout << std::endl;
}
Output
1, 434, 341, 158, 498
5, 316, 211, 323, 269
42, 508, 645, 232, 2
See a complete working sample of the code here please.
Upvotes: 0
Reputation: 133122
if
if(pixelvalue.length() == 0)
doesn't help, then it's not empty, but has some spaces in it. In particular, the last element of the row is the newline character. Trim the string before checking it for emptiness
boost::trim(pixelvalue);
if(pixelvalue.empty()) ...
For more information on trimming, see this question.
Alternatively, first read the whole line into a string, without the line terminating character, then read values from the string.
string line;
while(getline(file, line))
{
//optionally trim the line here.
istringstream iss(line);
string value;
while(getline(iss, value, ',')
cout << value << endl;
}
Upvotes: 2
Reputation: 1377
Use strtol to convert to long value & print only if its non-zero value.
pixelbits = strtol (pixelvalue.c_str(),&pEnd,16);
if(pixelbits)
cout << pixelvalue << endl;
Upvotes: 0