The discussion revolves around a mysterious error encountered in a C++ program where two identical code blocks are used, but only one compiles successfully. The user initially copied the content from a working `main()` function to a non-working one, yet the latter produced a compile error due to a missing `int` before `main()`. Participants emphasized the importance of checking compiler error messages, as they can guide users to the source of the issue, which in this case was the incorrect function signature. Additionally, it was clarified that compile errors prevent the creation of an executable file, while link errors occur after an object file is generated. The conversation highlights the need for careful attention to detail in coding and understanding compiler feedback.
I agree, and in the long run, I think that pbuk's comments were more helpful than mine.
That's nice of you ##-## I think that it's a toss-up there. Both of you guys make me wish that I could give more than one 'like' per post.
Last edited:
#53
yungman
5,741
294
Mark44 said:
Here's the code in question:
C++:
while (!dataFile.eof())
{
dataFile >> Ar;
cout << Ar << " ";// print out content read from file
}
cout << "\n\n after reading \n\n";
cout << Ar << "\n\n";//try to print out again.
The while loop reads one "word" at a time from the input file, with Ar being successively set to Jane, Murphy, and so on. The next to last read puts the string 28702 into Ar. The last read puts the null character into Ar, which now has \0, '8', '7', '0', '2', and the loop exits.
The first output statement prints the prompt. The second prints the string whose 0-index character is the null character, so nothing appears.
When you loop through Ar in the final loop, you get \0, '8', '7', '0', '2' and whatever garbage happens to be left over in the array.
You should work on getting more familiar with the debugger -- it can show you step by step what is happening.
Thanks for the reply. How do you find the debugger? I ran the program, it just ran, no information. How do you bring up the debugger? You mean in the Debug menu? I never even use that before.
This is the code what the book use, I read the code and I just don't feel it's right, dataFile >> Ar just kept writing to the beginning of the Ar, so it erase the last write. That prompted me to double check what is really inside the Ar after reading the complete file. I don't need the debugger to tell me. What if I need the whole content of the file and work on it?
I guess I mainly want to verify with you guys here. Then I can concentrate on how to read the entire file into the program instead of just printing it out with cout.
Thanks
Last edited:
#54
yungman
5,741
294
pbuk said:
I don't think it will do you any good if you were told why the code does not do what you expect it to. You should work it out for yourself:
Work through each line of the code on paper, working out the contents of each variable after each operation.
Insert some debugging code to check that what is happening is what you really think is happening. Bear in mind that a char type can contain values from 0-255; not all of these values translate to characters that will display on the screen so it is pointless using cout on a character array/C-string type, how can you display the ASCII code of each 'character' instead? (hint: the code stored in Ar[0] at the end of the program is a big clue to what is going on).
Think carefully about your control structures: how many times does your while (!dataFile.eof()) loop execute? Check your answer with some debugging code. This should give you some insight into what values Ar is taking as your code executes; again, check this with debugging code.
In summary it is not possible to debug programs by staring at the code saying 'this must be right' or by looking things up on the internet. You debug code by printing out values of variables at key points (or when you are desparate, after every statement) until you understand why it is not doing what you want it to.
Thanks for the reply.
I actually went through a lot of these. I did not post the stuffs I did at the interim on I actually put a counter how may times the while (!dataFile.eof()) ran.
This is from the book how it read out, I actually question whether it is right, I don't even assume it is right. That's the whole experiment I did yesterday when I ran into problem with VS. Just by analyzing the code, I don't think it really copy the file into the array Ar[].
I don't dare to come right out to say the book is wrong! That's why I phrase it in the question "how come I don't get the content I expect" instead. the book use this same while loop to read in the next few exercise, far as I concern, they NEVER manage to read the complete content of the file into the program. I think I show that already. I just want to confirm this, then I can move on coming up with a way to actually read the whole content of the file.
You mean in the Debug menu? I never even use that before.
Yes, the Debug menu. Yes, I can tell that you haven't used it.
yungman said:
I don't need the debugger to tell me.
Clearly you do need to use it, or you would have been able to understand why your program produced the output that you showed. Output statements can be helpful at times, but they are a very primitive way to debug a program.
yungman said:
I guess I mainly want to verify with you guys here.
I think I can speak for all of us that we would prefer that you make more of an attempt to answer the many questions you raise. The best way to do that is to learn how to use the debug capabilities.
#56
yungman
5,741
294
Mark44 said:
Yes, the Debug menu. Yes, I can tell that you haven't used it.
Clearly you do need to use it, or you would have been able to understand why your program produced the output that you showed. Output statements can be helpful at times, but they are a very primitive way to debug a program.
I think I can speak for all of us that we would prefer that you make more of an attempt to answer the many questions you raise. The best way to do that is to learn how to use the debug capabilities.
So you agree with me that the way of reading into Ar[] according to the book doesn't really copy the content of the file? Just use it to do cout to print it out. That's really what I was trying to ask. If so, I'll find another way to do it.
I am looking into modifying the program using vector and use push_back to copy the complete content of the file into the vector. What is the point of reading the file if one cannot actually copy the file into the program so the program can work on it?
So you agree with me that the way of reading into Ar[] according to the book doesn't really copy the content of the file? Just use it to do cout to print it out. That's really what I was trying to ask. If so, I'll find another way to do it.
The string gets written to the character array with no problem, but using the stream insertion operator, <<, to output it to cout is where the problem lies. The << operator doesn't work well with C-type character arrays. The C standard library functions printf() and scanf() (or scanf_s() when you're using VS) work better with C-type arrays than do the C++ classes, IMO.
yungman said:
I am looking into modifying the program using vector and use push_back to copy the complete content of the file into the vector. What is the point of reading the file if one cannot actually copy the file into the program so the program can work on it?
Using the vector template class isn't scalable. It would be OK for a toy program, but what if the file is 3.0 GB or 5.0 TB? It makes more sense to use a C++ string template class.
C++:
#include <string>
...
string str;
while (!dataFile.eof())
{
getline(dataFile, str);
cout << str ;// print out content read from file
}
Here getline() reads characters from the input stream up to the newline character, and writes them to str. The newline character is discarded each time it is encountered.
So you agree with me that the way of reading into Ar[]
It would be helpful to you to get the reading and writing terminology straight. You're not "reading into Ar[]" -- you're reading from the input stream (the file), and writing to the array. The words that we use affect how we think about things and how we communicate these ideas to others. Using the wrong words makes it more likely that we write incorrect code.
#59
yungman
5,741
294
Mark44 said:
The string gets written to the character array with no problem, but using the stream insertion operator, <<, to output it to cout is where the problem lies. The << operator doesn't work well with C-type character arrays. The C standard library functions printf() and scanf() (or scanf_s() when you're using VS) work better with C-type arrays than do the C++ classes, IMO.
Using the vector template class isn't scalable. It would be OK for a toy program, but what if the file is 3.0 GB or 5.0 TB? It makes more sense to use a C++ string template class.
C++:
#include <string>
...
string str;
while (!dataFile.eof())
{
getline(dataFile, str);
cout << str ;// print out content read from file
}
Here getline() reads characters from the input stream up to the newline character, and writes them to str. The newline character is discarded each time it is encountered.
I tried your suggestion, it still erase the old data in str every time a new line is read from file and write to str. I don't see this can achieve what I want...to read the stream from file and store the complete content into either an array or vector.
EDIT:
At the mean time, I was looking into using vector push_back and it works to a big extend. I saved all the content AND I can add space artificially. BUT I still yet to make the print out with other delimiters like '\n' for new line. This is what I learn online, this is ONLY the function part, but you should see what I am trying to do:
C++:
void showContents(fstream& file, vector<string>& vec)
{
char temp[MAX_LINE_SIZE];
while (!file.eof())
{
file >> temp;
vec.push_back(temp);
vec.push_back(" ");
}
cout << " Read back from file is: \n\n";
for (int index = 0; index < vec.size(); index++)
cout << vec[index];
}
I know you said using vector is not the best way, but until I can find another way, this is the only way I can think of with my limited knowledge.
Right now, I can save this in the vector : This is a test. Another test. More test. But I lost the new line. It should be: This is a test.
Another test.
More test.
You lost the newlines because the >> operator considers all "whitespace" to be the same: blank spaces, newlines and tabs. It reads "words" (groups of non-whitespace characters) without regard to the specific kind of whitespace that separates them. It discards the whitespace and gives you only the non-whitespace.
If you want to preserve the line structure of the file, you need to use getline(). It uses newlines as separators. Your code in post #59 is a good starting point for this. Simply use getline() instead of >> to read into temp.
getline() discards the newlines after using them as separators. It doesn't read them into the string. So if you want to display the strings on separate lines as they were in the file, you need to write the newlines yourself, using '\n' or endl.
I tried your suggestion, it still erase the old data in str every time a new line is read from file and write to str.
Of course it does. Each iteration of the loop resets str to a new value.
yungman said:
I don't see this can achieve what I want...to read the stream from file and store the complete content into either an array or vector.
I already said why this isn't a good idea for all but toy programs. If you run your program on a large file (several terabytes) the program will run out of memory.
#62
sysprog
2,617
1,796
Goodness gracious @Mark44 several terabytes? That seems to me to be like a really long movie. You could keep identification info on everyone on Earth in that much space. But yeah I recognize that nowadays some systems have petabytes and exabytes ##-## back in the day when I was barely a teenager (early '70s) we considered ourselves lucky that suddenly the IBM System 370 at the university had 12 megabytes of hand-threaded magnetic core memory ##\dots##
Goodness gracious @Mark44 several terabytes? That seems to me to be like a really long movie. You could keep identification info on everyone on Earth in that much space. But yeah I recognize that nowadays some systems have petabytes and exabytes − back in the day when I was barely a teenager (early '70s) we considered ourselves lucky that suddenly the IBM System 370 at the university had 12 megabytes of hand-threaded magnetic core memory …
I see that you can buy an 8TB Seagate SATA hard drive for $155 at the moment.
With regard to yungman's desire to keep all the data in memory, Windows imposes some limits on memory usage. (See https://software.intel.com/content/...dows. There are three kinds of memory limits:)
For 32-bit programs:
Static data - 2GB
Dynamic data - 2GB
Stack data - 1GB
But this doesn't mean you have 5GB to play with. The sum total of all three types has to be less than 2GB, and practically speaking it's about 1.75GB due to memory used by Windows.
For 64-bit programs, the limits are the same for static and stack data, but higher for dynamic data, but dependent on the particular version of Windows (i.e., Win 10 Enterprise, Win 10 Home, Win 8, Server editions, etc.).
Goodness gracious @Mark44 several terabytes? That seems to me to be like a really long movie. You could keep identification info on everyone on Earth in that much space. But yeah I recognize that nowadays some systems have petabytes and exabytes ##-## back in the day when I was barely a teenager (early '70s) we considered ourselves lucky that suddenly the IBM System 370 at the university had 12 megabytes of hand-threaded magnetic core memory ##\dots##
Well if it is a movie file then treating it as a \n separated text file is not going to work anyway.
Which is kind of the point - the whole reason streams exist is so that you don't have to load a whole file into memory to process it.
Output statements can be helpful at times, but they are a very primitive way to debug a program.
Yes you are right - the debugging capabilities of a powerful IDE such as VS are much more useful than cout.
#66
yungman
5,741
294
Mark44 said:
Of course it does. Each iteration of the loop resets str to a new value.
I already said why this isn't a good idea for all but toy programs. If you run your program on a large file (several terabytes) the program will run out of memory.
Not all files are that long, I just want to know how to do it. What if people want to look at bigger portion of the file to do modification, you cannot just read one line at a time. What you suggested is just slightly better than the original way the book use. Have to use common sense not to do it if it is the whole book! Most are just short files.
Like I said, I found two ways, the new way is even a little better than using vector, I just getline.(file, st1) to read the file into string st1; then str.append(st1) to assemble back the whole file. This will give the space between words, just cannot do new line.
Like I said, I found two ways, the new way is even a little better than using vector, I just getline.(file, st1) to read the file into string st1; then str.append(st1) to assemble back the whole file. This will give the space between words, just cannot do new line.
This might work, but I didn't try it. Each time after you call str.append(st1), append a newline character to str.
#68
yungman
5,741
294
Mark44 said:
This might work, but I didn't try it. Each time after you call str.append(st1), append a newline character to str.
Thanks, I just want to find a way to do it before I move on. I sure learn a lot digging back into strings.
#69
sysprog
2,617
1,796
This is plain C rather than C++ ##-## it's an example of nifty memory conservation ##-## (I copied this example from a wikipedia article and added some comments):
C:
void XorSwap( int* x, int* y )
{
/* ensure that you're not swapping a location with itself
(3 XORs would zero it out as surely as 1 XOR would) */
if (x != y)
{
*x ^= *y; /* xor x with y and store the result at x */
*y ^= *x; /* xor y with x and store the result at y */
*x ^= *y; /* xor x with y and store the result at x */
/* x and y have been swapped without a 3rd memory location */
}
}
For @yungman, who is a hardware guy: this is analogous to using 3 XOR (or 12 NAND (or XNOR (or with inverters AND or OR))) gates to keep a crossover planar.
from https://www.chegg.com/homework-help/questions-and-answers/complete-crossover-gadget-figure-511-hence-reduction-circuit-sat-planar-circuit-sat-design-q28238847:
The point that I'm trying to make here is that trying to not treat memory as if it were inexhaustibly freely available is something that programmers have conscientiously and inventively borne in mind, wherefore, I think that it might be good for you to try to follow some of the examples, and not try to read an entire file into local memory, only so that you can then display its contents ##-## I think that this point may be worth a few think-time moments for you.
Last edited:
#70
yungman
5,741
294
sysprog said:
This is plain C rather than C++ ##-## it's an example of nifty memory conservation ##-## (I copied this example from a wikipedia article and added some comments):
C:
void XorSwap( int* x, int* y )
{
/* ensure that you're not swapping a location with itself
(3 XORs would zero it out as surely as 1 XOR would) */
if (x != y)
{
*x ^= *y; /* xor x with y and store the result at x */
*y ^= *x; /* xor y with x and store the result at y */
*x ^= *y; /* xor x with y and store the result at x */
/* x and y have been swapped without a 3rd memory location */
}
}
For @yungman, who is a hardware guy: this is analogous to using 3 XOR (or 12 NAND (or XNOR (or with inverters AND or OR))) gates to keep a crossover planar.
from https://www.chegg.com/homework-help/questions-and-answers/complete-crossover-gadget-figure-511-hence-reduction-circuit-sat-planar-circuit-sat-design-q28238847:
The point that I'm trying to make here is that trying to not treat memory as if it were inexhaustibly freely available is something that programmers have conscientiously and inventively borne in mind, wherefore, I think that it might be good for you to try to follow some of the examples, and not try to read an entire file into local memory, only so that you can then display its contents ##-## I think that this point may be worth a few think-time moments for you.
My point is NOT about whether reading the whole file is good or not good. The point is I want to be able to read the whole file IF I want to, not that I have to. What bordered me was there are at least 4 sample programs in the book that "claim" reading from file and they are NOT. That bugs me to no end and I have to spend a day to find a way that can actually read the whole file. The book to me is misrepresentation. People can read it and thinking they actually read the whole file, but it's NOT. They just read a sentence and print out and erase it right away with another sentence.
I found the way and can read the delimiters also.
C++:
void showContents(fstream& file, string& str)
{
string str1;
while (!file.eof())
{
getline(file, str1);
str.append(str1);
}
cout << "Now read back from str: \n\n" << str << "\n\n";
}
I know if I want to do search character of a string str using str.find(), I can pull in one sentence at a time, no need to pull the entire file. I just want to know I can do it.
#71
sysprog
2,617
1,796
Reading the file iteratively (read a part, do something with it, then read the next part) is different from reading the whole file into memory before doing anything with any part of it. As @Mark44 pointed out, you can't do that with a very large file ##-## please look at the Hubbard C++ data structures book that you recently purchased ##-## it has many coding examples and explanations. I think that your reading of some it may help to further inform you for your interpretation of the Gaddis book code.