Home Assignment doesn't work but address of with the dereference operator does?
Reply: 3

Assignment doesn't work but address of with the dereference operator does?

TimTheEnchanter
1#
TimTheEnchanter Published in 2018-02-13 21:54:27Z

I've been playing around with C++ (just starting out), and I'm trying to make a program that needs a function to count the lines in C++. However, I've encountered weird behavior where normal assignment doesn't work, but assignment through address of, and then immediate dereference does. Like this:

int countLinesInFile(string fileName){
  char c[32];
  int numLines = 0;
  ifstream file(fileName);

  while(file >> c){
    numLines += 1;
    cout << "Lines: " << numLines << endl;
  }
  return numLines;
}

Which results in:

Lines: 1
Lines: 1
Lines: 1
Lines: 1
Lines: 1
Lines: 1

However, when I change numLines += 1 to *(&numLines) += 1 it magically works:

Lines: 1
Lines: 2
Lines: 3
Lines: 4
Lines: 5
Lines: 6

For a little background, the file I'm reading is a 6 line file where each line is a 32 bit binary string (equal to zero). When I print out c (with cout << c) it prints out seemingly correctly. Also, I am aware that this may not be the optimal or correct way of doing read lines from a file, but unless this simply can not possibly work, I am more interested in the underlying mechanics of why this behavior is happening, and what I am doing wrong.

Benjamin Barrois
2#
Benjamin Barrois Reply to 2018-02-13 22:14:58Z

'\0' character binary value is 00000000. I guess that numLines is just after your array c in memory and is always erased with zeros, before being incremented by 1. So it always displays as 1.

When you compile the second version, the memory must be organized another way (only the compiler knows, and you if you debug at very low level), which does not impact numLines value.

TimTheEnchanter
3#
TimTheEnchanter Reply to 2018-02-13 22:09:14Z

Well, here's the answer. As StoryTeller said, the array must be 33 characters long in order to capture the terminating character and prevent the unusual behavior.

P.S. Thank you for all the helpful comments, and I agree that getline is probably a better alternative. If anyone has any insight as to how exactly this overflow might cause this weird behavior that would be very welcome.

Raindrop7
4#
Raindrop7 Reply to 2018-02-13 22:14:35Z

Use class std::string with the API std::getline where you can read a whole line at each read and increment at each read the counter variable:

std::string sLine;
std::ifstream in("main.cpp");
int nLines = 0;

while(std::getline(in, sLine))
    ++nLines;
std::cout << nLines << endl;

in.close();
You need to login account before you can post.

About| Privacy statement| Terms of Service| Advertising| Contact us| Help| Sitemap|
Processed in 0.313129 second(s) , Gzip On .

© 2016 Powered by mzan.com design MATCHINFO