LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 10-26-2019, 06:25 AM   #91
GazL
LQ Veteran
 
Registered: May 2008
Posts: 6,897

Rep: Reputation: 5018Reputation: 5018Reputation: 5018Reputation: 5018Reputation: 5018Reputation: 5018Reputation: 5018Reputation: 5018Reputation: 5018Reputation: 5018Reputation: 5018

Quote:
Originally Posted by jsbjsb001 View Post
No, I tried the printf() astrogeek gave me before, I've tried looking at the code, but I really don't know why it'll stop before it gets to the newline character.
Pretend to be a computer. Imagine your input line is the six characters <space> <space> <a> <b> <\n> <\0>, step through the code of your for loop in your mind, statement by statement, and do what each statement tells you to do. Use a piece of scrap paper or something to write down the values of the variables as you go Pay attention to which statements get run and what they do.

Playing pretend is something programmers have to do a lot, and it's an essential skill to learn. You're not going to get anywhere without it.
 
3 members found this post helpful.
Old 10-26-2019, 07:29 AM   #92
BW-userx
LQ Guru
 
Registered: Sep 2013
Location: Somewhere in my head.
Distribution: Slackware (15 current), Slack15, Ubuntu studio, MX Linux, FreeBSD 13.1, WIn10
Posts: 10,342

Rep: Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242
Quote:
Originally Posted by jsbjsb001 View Post
...removed for length ...


Well hello BW... this is exactly what I'm talking about above, it's hard enough just trying to understand one problem, let alone when, and to use your words, "someone throws yet another fish in the barrel". In other words; how on earth am I supposed to understand the example given in post #33 if I can't understand why what I'm trying to do without pointers isn't working the way I've intended it to ? Among the fact I don't fully understand how that code works, this is why I'm trying to take it one step at a time. That way, I can SEE the different versions of the program, and hopefully be able to get a better understanding of WHY the code in post #33 is "so much better".



Can I ask that we just focus on the problem at hand, and keep the discussion concerning the C programming language - things are hard enough as it is, thanks. And also, I'm not currently trying to learn Perl or Python, nor trying to write a Perl or Python program.

After I got that to work, and posted it, I still had to go back and look at it, to completely figured out why it is doing what it was doing.

sometimes I just put basic concepts together that look logical to me, after I wrote out what I did, to just find the # then print that and everything after that, then set out to do using what was already there. Seeing in this post it looked to me that that one for loop was being held the all important one to work with.

then you see the results of it.

I'll put comments in it and hopefully do not clutter up the code too much so you can follow it.
Code:
   printf("-------- print the comment parts ---------------------------\n");
    while ( fgets(content, CONTENT_LEN, testfile) != NULL ) {

          for ( i = 0; content[i] != '\0'; i++ ) {
			  if (content[i] == '#')
			{
				for ( int f = i; content[f] != '\0' ; f++) {
					printf("%c", content[f]);
				}
			}

		}
	}
	printf("-------- print the no comment parts ---------------------------\n");
    rewind(testfile); // rewinds the file. 
    int f = 0;
// feed the for loop CONTENT_LEN 373 chars at a time 
	while ( fgets(content, CONTENT_LEN, testfile) != NULL ) {
     //to look at each char separately, while treating the complete
     //content as a complete line within the file (depending on the logic of the
     //programmer) using the given size of CONTENT_LEN. it runs until EOL is hit
     //then resets its counter i=0 while being feed by the while loop
		for ( i = 0; content[i] != '\0'; i++ ) {
			//look for the # to indicate a comment
			//whence found put that into another loop
			//to run that string out to the end while not printing it
			//rather in order to skip it. 
			//pass the count value to another variable so as to 
			//not mess up the original count for the over all file
			if (content[i] == '#')
			{   // the logic behind this is.
				//anything that starts with the # is a comment
				//because  (mostly) I the programmer said so.
				//therefore this same type of loop above
				//is now running until it hits NULL (end of line).
				// as the "rules" for # as a comment it has to be 
				//in front of each line on each line to indicate
				//a comment.
				  //so this works # -> until \0 or EOL on that one
				//line.
				//give back count i = f then break out of it.
				//to get the next line in the file. if you 
				//remove the all of this code below until
				//you get to the printf("\n")
				//then run it you will see why that is needed.
				//
				for ( f = i; content[f] != '\0' ; f++) {
					//printf("%c", content[f]);
					; // just run it to the end
				}
				i = f;
				break;  // kick it back to the outer for loop
			} //here if you picture in your mind the line with the comment
			//#comment here lalalala
			// the above if is looking for an '#' to kick in and do what it does.
			//if no # it then passes the same char down to look at it, 
			//this does the opposite, just to be sure check, if not # then print that same char.
			
				if (content[i] != '#') {
					printf("%c",content[i]);
				}

			} //the output still needs a new line if an # is encountered within the line itself
			// code #comment
			//code .. so if the first if () is printing and done, kick it out 
			//so it does not check anything afterwords keeping the where it
			//left off count and skipping the second if check, therefore
			 //it then goes down to here the new line printf("\n"); 
			//before it goes back up to the first for to control the
			//check for NULL moment within the file. NULL being hitting the end of the 
			//page on the right side. then next line. (someone correct me if I 
			//wrong in that assessment).

 			printf("\n");

	}
	//the while loop is the control loop for the file being read it stops
	//feeding the program when it hits NULL eof End of File. 

    fclose(testfile);
    free(filename);

    return 0;
}
in order to actually see the code working, you need to put it into a debugger then step on each line to follow it and see where its going and how it actually working using the values of the variables. CODE BLOCKS has a debugger IDE for gdb too. that might be easier whence you figure that part out, how to use it.

if you choose to go that far.

you can remove this
Code:
//if (content[i] != '#') 
{
	printf("%c",content[i]);
}
then just leave the printf to reduce lag in the code. it is actually an unnecessary check. Logic states if not # then print it, and the for loop takes care of what is after the # to end of line (EOL).


then after you've ran that code. comment out the break recompile then run it again to see what the break is doing, or forbidding being done. Especially where you have a comment in the code like this.
Code:
code here #comment here
 no comment#
 #Here is a comment
some more code here
maybe a little clearer for a few things within the code. The break and how the data is being looked at.
Code:
  int f = 0, b = 0;
	printf("outside while\n");
	while ( fgets(content, CONTENT_LEN, testfile) != NULL ) 
	{
		for ( i = 0; content[i] != '\0'; i++ ) 
		{
			if (content[i] == '#')
			{   //anything after # is part of the comment
				// nothing under this for loop still causes it to run to EOL
				// { } can be used to not confuse compilers
				// and them that do not fully understand
				//the rules of coding. Where this is legal
				//when some might not think it is. 
				
                                for ( f = i; content[f] != '\0' ; f++) 
				
				
				//so the outer for loop can pick up
				//where the inner for loop left off at. 
				// i = f;	
				i = f;
				break;
					  
			} //end if
                         // content[i] will not equal '#' 
			//deductive reasoning is being applied here. 
			printf("%c",content[i]);
		} //END OUTER FOR LOOP

		//Since EOL has been hit in the inner for loop within the if (),
		// to  prevent it from printing the next i count on content[i] 
		//that maybe on the next line in the file.
		//the use of the break kicks it out of the outer for loop preventing that.
		//because the break's action is based on the if ( content[i] == # ) 
		//block of code.
		// 
		//Because it is still inside of the while loop, this causes the code 
		//to pick it back up where it left off at on the inner for loop.
		//or anywhere within the outer for loop.
		//
		//Because the break or the outer for loop hits \0 therefore 
		//taking it out of the outer for loop yet still
		//it is kept within the while loop. 
		//
		//Thereby this printf command is to insure a new line is printed 
		//in the output. So two lines within the file will not be put 
		//together on the same line inthe output due to the how the
		//stream is being looked at by the use of the 'i' value.

		 printf("\n");

	} //END WHILE
	//the while loop is the control loop for the file being read it stops
	//feeding the program when it hits NULL eof End of File.
Logic being applied.
1. open file
2. find comments, remove them.
3. Print out whats left.
4. close file.

Last edited by BW-userx; 10-26-2019 at 09:11 AM.
 
Old 10-26-2019, 02:28 PM   #93
rtmistler
Moderator
 
Registered: Mar 2011
Location: USA
Distribution: MINT Debian, Angstrom, SUSE, Ubuntu, Debian
Posts: 9,882
Blog Entries: 13

Rep: Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930
@jsbjsb001,

Recommend your next experiment start with a clear text description of your intended program, and discussion of the design to complete it, before you write any code.
 
Old 10-26-2019, 10:35 PM   #94
astrogeek
Moderator
 
Registered: Oct 2008
Distribution: Slackware [64]-X.{0|1|2|37|-current} ::12<=X<=15, FreeBSD_12{.0|.1}
Posts: 6,263
Blog Entries: 24

Rep: Reputation: 4194Reputation: 4194Reputation: 4194Reputation: 4194Reputation: 4194Reputation: 4194Reputation: 4194Reputation: 4194Reputation: 4194Reputation: 4194Reputation: 4194
I have been following this thread, but without much direct participation since initial comments where I tried to focus attention very narrowly on getting jsbjsb001 to try to understand the code he originally wrote.

Quote:
Originally Posted by astrogeek View Post
Please everyone, let's refrain from offering better ways of checking for comment lines and help jsbjsb001 to understand the behavior of his particular loop code, whether we think it is not the best way to perform the task or not.
But I think this is an appropriate point to interject a few comments about why we are here, again, other than simple programming déjà vu. There is an underlying difficulty present here that causes all of us, jsbjsb001 and those providing help, to return to the same points repeatedly.

The real difficulty that has not been overcome is the unfortunate absence of basic math, in particular basic algebra skills, from jsbjsb001's early education as noted in his early C programming threads. It is not simply that he is, as he himself says, "no good at math". It seems to me it is because a whole system of thought, a way of thinking, which most of us believe to be inherent in our natures, actually comes to us via our early math education.

Because we assume others have more or less the same innate foundation for understanding the concepts which we have, we try to communicate the help we offer at the higher syntactic level, but repeatedly we are all frustrated, most of all jsbjsb001, to find that the block to our progress is actually at a different level, call it the semantic level.

In other words, although jsbjsb001 is learning the syntax (rules) of the programming language, what he is really missing is the semantics (meaning of it all). At the same time, the rest of us have assumed he knows the meaning and have remained focused on the code, the syntax. This has been noted by others as well, for example:

Quote:
Originally Posted by rtmistler View Post
It's not just about getting syntax correct.
As I self-quoted above, we need to "focus attention very narrowly on getting jsbjsb001 to try to understand the code he originally wrote". This is the very block noted by rtmistler:

Quote:
Originally Posted by rtmistler View Post
I feel this is the key question. If they do not understand the problem with how they've coded this for() loop statement, then this is a blocking situation.
And here is how this block manifests itself over and over. First, very useful and correct advice is given about how to approach programming problems (quoted posts out of order, but point remains the same)...

Quote:
Originally Posted by GazL View Post
Pretend to be a computer. Imagine your input line is the six characters <space> <space> <a> <b> <\n> <\0>, step through the code of your for loop in your mind, statement by statement, and do what each statement tells you to do. Use a piece of scrap paper or something to write down the values of the variables as you go Pay attention to which statements get run and what they do.

Playing pretend is something programmers have to do a lot, and it's an essential skill to learn. You're not going to get anywhere without it.
But this advice makes the implicit assumption that the person is innately able to understand, or reason their way through that loop in much the same way that the advice giver does. But when that is not actually the case, this happens:

Quote:
Originally Posted by jsbjsb001 View Post
No, I tried the printf() astrogeek gave me before, I've tried looking at the code, but I really don't know why it'll stop before it gets to the newline character.
..
Can I ask that we just focus on the problem at hand, and keep the discussion concerning the C programming language - things are hard enough as it is, thanks. And also, I'm not currently trying to learn Perl or Python, nor trying to write a Perl or Python program.
So everyone continues to look for a code based explanation. But more and more pages of code are not beneficial to the understanding if you are not able to "run" the concepts in your head! In fact, more and more code only obscures the problem and ultimately proves frustrating for all concerned, not least of all for jsbjsb001 himself.

The intent of my post here is to try to get us all to focus on the actual problem and help jsbjsb001 acquire the basic math skills the rest of us take for granted. I am not thinking here about better skills at addition and subtraction, but slightly more abstract skills, especially how to think algorithmically. The basic loop on which most of this thread has focused is a simple, stand alone algorithm which jsbjsb001 has not yet understood - let's pool our efforts to figure out how to give him the ability to understand the algorithm independent of the code.

And I am asking jsbjsb001 to realize that there is no simple answer for many of his questions in the code. So please heed this advice, it leads in the right direction:

Quote:
Originally Posted by rtmistler View Post
@jsbjsb001,

Recommend your next experiment start with a clear text description of your intended program, and discussion of the design to complete it, before you write any code.
Apply the same standard when asking programming questions. Rather than writing code and posting it as the primary description of some problem, present your questions as a simplest possible textual description, or specification of what you want to accomplish, along with a textual description of the algorithm you are thinking of using. You will be surprised how quickly you begin to think in terms of the problem instead of in terms of the code, and most code problems will then resolve themselves.

I would also suggest using any convenient non-code notation you can draw with pencil and paper to describe any task for which you might want to write a program. Simple flow charts, psuedo code, little boxes and circles connected by arrows - make up your own! The poiint is that you need to have a clear mental image of what you want to do, and some way to express that other than the syntax of some programming language. Anything at all will do so long as you can look at it a day later and understand what you meant!

Indeed, the proper place of programming is actually one of translation from one language, the mental representation of what is to be done as expressed in human language and math notations, to another, be it C, perl, bash, python, etc., etc. Trying to write valid code syntax first, then to understand what it does, is a very difficult path for all.

And to be very, very clear about these comments - I am in no way criticizing anyone, least of all jsbjsb001! He has acquired his knowledge of computing and Linux himself, and has used it all to help others here at LQ! He has excellent language and communications skills and has demonstrated repeatedly his eagerness to learn. It is not his fault that one key area of his education was deficient, it is simply, as they say at the poker table, the hand life has dealt him.

He is looking to improve his hand and all we here are trying to help him do that! The best path to success is always to understand clearly the underlying problem and fix it - so let's work on that problem and help him draw the best possible hand.

Last edited by astrogeek; 10-26-2019 at 11:44 PM.
 
3 members found this post helpful.
Old 10-27-2019, 04:59 AM   #95
jsbjsb001
Senior Member
 
Registered: Mar 2009
Location: Earth, unfortunately...
Distribution: Currently: OpenMandriva. Previously: openSUSE, PCLinuxOS, CentOS, among others over the years.
Posts: 3,881

Original Poster
Rep: Reputation: 2063Reputation: 2063Reputation: 2063Reputation: 2063Reputation: 2063Reputation: 2063Reputation: 2063Reputation: 2063Reputation: 2063Reputation: 2063Reputation: 2063
Thanks again guys.

I'll try what you said GazL, thanks again for your help.

BW, I might leave trying to understand your code for later on. But thanks for your help tho.

In relation to RT's comment above; I didn't want to come off as someone just asking for a hand-out, and not making any effort of my own. That's why I tried to at least write some code, even if I wasn't exactly sure how to write what I intended properly. Because I know how frustrating it can be when I try and answer a non-programming related technical question here and being treated like a help-desk.

In relation to astro's comments; that's pretty much the case, it's not hard to understand what an if statement is and does, but when I've got loops involved, particularly nested loops, nested if's, etc, it can be mindboggling to try and understand exactly what's going on when I run it. Even if I step through the program and look at the statements in it, like astro was saying above, it is still very difficult to try and step through exactly what's going on in my mind without actually seeing what exactly is happening.
 
Old 10-27-2019, 07:54 AM   #96
GazL
LQ Veteran
 
Registered: May 2008
Posts: 6,897

Rep: Reputation: 5018Reputation: 5018Reputation: 5018Reputation: 5018Reputation: 5018Reputation: 5018Reputation: 5018Reputation: 5018Reputation: 5018Reputation: 5018Reputation: 5018
When tracking a squirrel through the woods, it's much easier if you don't worry about which trees it's not in, but instead focus only on the one it is in¹. The computer processor doesn't care about nested 'if's or loops. It only knows about the current statement and any variables it might use.

It sounds like you're trying to keep a full picture of your program in your mind, and that quickly becomes too much of an ask as a program gets larger: even for the best of us (which is definitely not me!). When trying to understand code, focus on the small details and don't worry about the big picture.

If you get stuck with the single-stepping, I'll run through it for you, just let me know below.


Programming is all about breaking a problem into smaller, more manageable parts, and then solving those. If you're seeing too many nested ifs/loops then chances are you didn't break it into enough parts. Using functions can help a lot.

So, lets do that.

First, define the problem:
Read through all lines in a file: for each line that doesn't start with a # (optionally proceeded by any number of spaces), print it out.
And then, write an outline, breaking that into solvable parts:
1) open the file, checking for errors.
2) loop over the file reading each line
3) do something for each line:
Then we break part 3 into solvable parts:
3a) skip over zero or more spaces.
3b) check if the character is a '#', if not, do part 3c.
3c) print the line.
it should be clear that parts 3a..3c can be put into a separate function that can then be considered a single part 'part 3' in the main loop of the program. If part 3c was more complicated than "print the line" one would most likely break that into its own part 'part 4', possibly in its own function, and so on.

See how clean and easy it becomes when you start the right way? Non of those individual parts are hard to understand, or code. This is what rtmistler and astro' were hinting at above about defining/designing before you start to code.

--
¹ I must have read that somewhere.

Last edited by GazL; 10-27-2019 at 08:33 AM.
 
2 members found this post helpful.
Old 10-27-2019, 09:10 AM   #97
rtmistler
Moderator
 
Registered: Mar 2011
Location: USA
Distribution: MINT Debian, Angstrom, SUSE, Ubuntu, Debian
Posts: 9,882
Blog Entries: 13

Rep: Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930
One technique I've used formerly was to make a variable table, an excel spreadsheet.

Variable names across the top, rows designate program execution steps.

Just another way to single step through your design.

If you make assumptions, you'll stand to fail.

Examples:

Assuming an uninitialized variable is initialized.

Assuming some part works, without having fully tested it, and skipping it in the process.

@Astrogeek,

Very well points made.
 
3 members found this post helpful.
Old 10-27-2019, 09:47 AM   #98
jsbjsb001
Senior Member
 
Registered: Mar 2009
Location: Earth, unfortunately...
Distribution: Currently: OpenMandriva. Previously: openSUSE, PCLinuxOS, CentOS, among others over the years.
Posts: 3,881

Original Poster
Rep: Reputation: 2063Reputation: 2063Reputation: 2063Reputation: 2063Reputation: 2063Reputation: 2063Reputation: 2063Reputation: 2063Reputation: 2063Reputation: 2063Reputation: 2063
Thanks again guys.

Like I was saying before, the concepts by themselves at least for the most part seem to be ok, although loops are proving to be hard to keep track of - particularly with nested if's, etc within them. Even when I try and step through what's going on line by line/one line at a time, I tend to lose track of it, even if I try and just focus on the one loop, like just the for loop in my program above. It's basically like astro was saying above, in that; it's first trying to get a firm understanding of the algorithm concerned, then even when I've got that, trying to keep track of where it's currently up to, and why it's at the point it's at, then trying to keep track of whatever else is involved. It just seems that I end up getting completely lost each and every time, regardless of what I try to keep track of it - even trying to break it up in to small steps, I still seem to get lost.

It's ok if it's a tiny program that say for example just adds two numbers together, then prints the result. But when there's all kinds of concepts involved, particularly loops, more than just one variable, etc, I just end up getting lost and confused no matter what I seem to try.

I guess I'm just not used to following algorithms, and because of the hand I've been dealt in regards to the mathematics, like astro was talking about above, this is what is effectively blindfolding me each and every time. But like I said before I'll try what ya's have said above, and maybe that might make things easier, I donno.

If you want to go through single-stepping GazL, then I won't say no. Thanks again.
 
1 members found this post helpful.
Old 10-27-2019, 11:55 AM   #99
GazL
LQ Veteran
 
Registered: May 2008
Posts: 6,897

Rep: Reputation: 5018Reputation: 5018Reputation: 5018Reputation: 5018Reputation: 5018Reputation: 5018Reputation: 5018Reputation: 5018Reputation: 5018Reputation: 5018Reputation: 5018
Ok, here's your code with line numbers:
Code:
     1  while ( fgets(content, CONTENT_LEN, testfile) != NULL ) {        
     2      for ( i = 0; content[i] != '\0'; i++ ) {
     3          if ( content[i] != ' ' ) {
     4              if ( content[i] == '\n' ) {
     5                  content[i] = '\0';
     6              }
     7              if ( (content[i] != '#') && (content[i] != '\0') ) {                               
     8                  printf("line[%s]\n", content);                                            
     9              }
    10              break;
    11          }                  
    12      }                
    13  }
Lets assume that fgets() has just read the line " ab", which will have the characters <space> <space> <a> <b> <\n> <\0>.
We start at line 2:
2: i is set to 0, content[i] is ' ' so content[i] != '\0' is true and the loop continues to line 3.
3: content[i] != ' ' is checked, content[i] is a ' ' so this test is false and the program skips the body of the if and continues at line 12.
12: we start the loop again, after increasing i by 1.
2: i is now 1, content[i] is another space so we repeat the above exactly as we did the first time through.
3: is false again, so we skip to 12.
12: i is incremented by 1 again, and around we go.
2: i is now 2. content[i] is now 'a', content[i] != '\0' is still true so we go to 3:
3: content[i] != ' ' is now true, so this time we go to 4 instead of skipping to 12.
4: content[i] == '\n' is false, so we skip to 7.
7: (content[i] != '#') && (content[i] != '\0') is true, so we run line 8.
8: prints the line, and we go to 10
10: BREAK, the loop stops. the program goes to line 13.
13: We go back to 1:

So, there's your problem. when content[i] is not a space, the loop will break at line 10.

Having said that, it's not fixable in its current form without introducing other issues, i.e. your printing the line on finding the first non space, non '#', so the \n replacing code will run too late.

Much better to rework it:
Code:
while ( fgets(content, CONTENT_LEN, testfile) != NULL ) {        
    size_t i = 0;
    while (content[i] == ' ' )
        ++i;
    if ( content[i] != '#' ) {
        for ( size_t j = i ; content[j] != '\0' ; ++j )
            if (content[j] == '\n' )
                content[j] = '\0';

        printf("line |%s|\n", content);
    }
}
 
2 members found this post helpful.
Old 10-27-2019, 12:33 PM   #100
BW-userx
LQ Guru
 
Registered: Sep 2013
Location: Somewhere in my head.
Distribution: Slackware (15 current), Slack15, Ubuntu studio, MX Linux, FreeBSD 13.1, WIn10
Posts: 10,342

Rep: Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242
Quote:
Originally Posted by jsbjsb001 View Post
BW, I might leave trying to understand your code for later on. But thanks for your help tho.
---removed for length--
Because Math has been mentioned, and true it is being used here as well. what is taking place is actually a simple line graph that you are working with here.

When you used the value of i to walk yourself down the string to check each character to identify the # as a beginning of a comment.

Code:
[0][1][2][3][4][5][6][7]
 b  o  b  #  m  a  k  e
If you can picture that in your head in some form for your own personal understanding. Then simple logic needs to be applied. walk down the string until the # is found, then apply basic comment rules to this logic.

remove that and everything from and after the # that indicates a comment on one line.

that is what the most inner loop is doing. it is continuing the count to walk down until the end of line is gotten. then the count value gets returned back to the original holder which is 'i' to continue walking down the string until it finds another # then in inner most loop takes over again, doing the same thing all over again.

being that you applied the printf to output the not a comments, then the inner loop just prevents that part of this continuous line from being printed out to the screen while continuing to walk the count down this line graph with EOL and \n and \0 within it for human readability on a screen that is only so wide.

It is outer for loop that prints out the rest of it.

I, myself, can't really do a logical flow chart in here.

While the while loop just feeds the line into the for loops.
Code:
1. while ( feeding the for loops until you hit NULL)
{
  2. for ( start feeding line by each char );
  3. if ( # char found ) 
  4. for ( starting walking it down the string until that end of line is hit)
  5. else No # is found in each char, so print that out.

} end of while
as stated simple math (adding and subtracting.) and deductive reasoning can even take care of this.

you are just counting each char down a line graph looking at each char
applying print, don't print to the equation depending on the condition.

Last edited by BW-userx; 10-27-2019 at 12:48 PM.
 
1 members found this post helpful.
Old 10-28-2019, 04:31 AM   #101
jsbjsb001
Senior Member
 
Registered: Mar 2009
Location: Earth, unfortunately...
Distribution: Currently: OpenMandriva. Previously: openSUSE, PCLinuxOS, CentOS, among others over the years.
Posts: 3,881

Original Poster
Rep: Reputation: 2063Reputation: 2063Reputation: 2063Reputation: 2063Reputation: 2063Reputation: 2063Reputation: 2063Reputation: 2063Reputation: 2063Reputation: 2063Reputation: 2063
Thanks guys.

Quote:
Originally Posted by GazL View Post
Ok, here's your code with line numbers:
[snipped]
Lets assume that fgets() has just read the line " ab", which will have the characters <space> <space> <a> <b> <\n> <\0>.
We start at line 2:
2: i is set to 0, content[i] is ' ' so content[i] != '\0' is true and the loop continues to line 3.
3: content[i] != ' ' is checked, content[i] is a ' ' so this test is false and the program skips the body of the if and continues at line 12.
12: we start the loop again, after increasing i by 1.

...
So, there's your problem. when content[i] is not a space, the loop will break at line 10.

Having said that, it's not fixable in its current form without introducing other issues, i.e. your printing the line on finding the first non space, non '#', so the \n replacing code will run too late.

Much better to rework it:
Code:
while ( fgets(content, CONTENT_LEN, testfile) != NULL ) {        
    size_t i = 0;
    while (content[i] == ' ' )
        ++i;
    if ( content[i] != '#' ) {
        for ( size_t j = i ; content[j] != '\0' ; ++j )
            if (content[j] == '\n' )
                content[j] = '\0';

        printf("line |%s|\n", content);
    }
}
Yeah, what I've highlighted in bold above is pretty much what was just not obvious to me. Like I said before, reading the code itself isn't really a problem, but like I said above, trying to follow what the loop is actually doing was virtually impossible. I knew it was reading at least some of the line fgets() uploaded into the array, but trying to work out where exactly it was at in the array, then trying to figure out what the value of it's index (i) was, then trying to predict what was going to happen next was just impossible no matter how many times I tried, no matter what I tried. Even just trying to think about only one line wasn't any easier. I couldn't even figure out when it has finished with one line before fgets() uploaded another line, even with using gdb to single step through it. While it does make more sense with your explanation above, it's still virtually impossible trying to do that in my head.

It's ok with the examples in the book, because as you know, he explains what's going on afterwards. But without that safety net, you're on your own. So like I said, trying to do it in my head without actually being able to see what's going on is like pin the tail on the donkey, complete with the blindfold on. So god only knows how I'm suppose to read someone else's code with loops, etc in it - particularly when I don't even have the benefit of knowing what they were thinking when they wrote it, if I can't even make sense of my own code.

Thanks for your post nonetheless GazL
 
Old 10-28-2019, 05:05 AM   #102
rtmistler
Moderator
 
Registered: Mar 2011
Location: USA
Distribution: MINT Debian, Angstrom, SUSE, Ubuntu, Debian
Posts: 9,882
Blog Entries: 13

Rep: Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930
Quote:
Originally Posted by jsbjsb001 View Post
Yeah, what I've highlighted in bold above is pretty much what was just not obvious to me.
Code:
2: i is set to 0, content[i] is ' ' so content[i] != '\0' is true and the loop continues to line 3.
3: content[i] != ' ' is checked, content[i] is a ' ' so this test is false and the program skips the body of the if and continues at line 12.
12: we start the loop again, after increasing i by 1.
So you've never gotten the original flaw?

SPACE in ASCII is 0x20 which in decimal is 32.

Using the "current array element" as your loop exit test is the problem when i became 32 and it was also pointing to a SPACE character.

content[i] with i=32 means content for that line, in that position was also 32.

Loop should've always been like
Code:
while(content[i] != EOL)

Last edited by rtmistler; 10-28-2019 at 06:24 AM.
 
Old 10-28-2019, 06:55 AM   #103
BW-userx
LQ Guru
 
Registered: Sep 2013
Location: Somewhere in my head.
Distribution: Slackware (15 current), Slack15, Ubuntu studio, MX Linux, FreeBSD 13.1, WIn10
Posts: 10,342

Rep: Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242Reputation: 2242
Just do loops
1. C exercises and solutions: loops in C
2. https://www.w3resource.com/c-program...loop/index.php
3. Loop programming exercises and solutions in C

do enough of them eventually you'll start to see what they are doing. Like that matrix movie .. you'll be able to read the code just by looking at it, and understand what it represents.

Last edited by BW-userx; 10-28-2019 at 06:57 AM.
 
Old 10-28-2019, 08:23 AM   #104
jsbjsb001
Senior Member
 
Registered: Mar 2009
Location: Earth, unfortunately...
Distribution: Currently: OpenMandriva. Previously: openSUSE, PCLinuxOS, CentOS, among others over the years.
Posts: 3,881

Original Poster
Rep: Reputation: 2063Reputation: 2063Reputation: 2063Reputation: 2063Reputation: 2063Reputation: 2063Reputation: 2063Reputation: 2063Reputation: 2063Reputation: 2063Reputation: 2063
Quote:
Originally Posted by rtmistler View Post
So you've never gotten the original flaw?

SPACE in ASCII is 0x20 which in decimal is 32.

Using the "current array element" as your loop exit test is the problem when i became 32 and it was also pointing to a SPACE character.

content[i] with i=32 means content for that line, in that position was also 32.

Loop should've always been like
Code:
while(content[i] != EOL)
Yes, I do understand the original problem - I understood that some posts ago now. I even said before that I'd even done some experimenting myself to confirm I was thinking right about it. I think you've misunderstood, and/or missed the point of what I was talking about. To put it briefly, it's not just about loops, and I do understand what a loop is and does, the same as I understand what if statements are and do. I'd suggest without trying to be rude, and I say this for a couple of reasons, you have another read of astrogeek's post #94. I could try and explain what I mean, but I think astro can probably do a better job of explaining the real problem here (which he seems to have nailed along with GazL, and I really think their absolutely right about it too). It's for what I can see, the same problem with pointers, again, I do understand what pointers are and do, and even at least some situations where I's use them, but trying to follow them particularly where you have if's, loops etc, I tend to have the same problem, then end up getting just as lost - particularly if there's problems with the code I've written.

Quote:
Originally Posted by BW-userx View Post
Just do loops
...
do enough of them eventually you'll start to see what they are doing. Like that matrix movie .. you'll be able to read the code just by looking at it, and understand what it represents.
BW, you were actually closer to the real problem I'm having in post #100. With all respect, I'd also suggest you read astro's post #94, as again, that seems to be the real problem. Loops, arrays, pointers, if's, etc are really just symptoms of that same problem AFAICS. But, and that said, it does seem a bit like the Matrix movies, and trying to crack the code of the matrix

But thanks again to the both of you for your continued help, and interest.
 
Old 10-28-2019, 10:04 AM   #105
rtmistler
Moderator
 
Registered: Mar 2011
Location: USA
Distribution: MINT Debian, Angstrom, SUSE, Ubuntu, Debian
Posts: 9,882
Blog Entries: 13

Rep: Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930
EDIT: Cut back to make more readable and be less argumentative:

This is how to think using an algorithm:

Text for first line and how you can think about it:
Code:
"line1\n\0"
{ 'l',  'i',  'n',  'e',  ' ',  '1',  \n,   \0   }
{ 0x6C, 0x69, 0x6E, 0x65, 0x20, 0x31, 0x0A, 0x00 }
Your original for() loop statement:
Code:
for ( i = 0; i < content[i]; i++ )
What this does for the first file line of text:
Code:
Step    i    content[i]    test         result of test    string at content[i]
------------------------------------------------------------------------------
0       0    l              0 < 0x6C    PASS/CONTINUE     line 1\n\0
1       1    i              1 < 0x69    PASS/CONTINUE     ine 1\n\0
2       2    n              2 < 0x6E    PASS/CONTINUE     ne 1\n\0
3       3    e              3 < 0x65    PASS/CONTINUE     e 1\n\0
4       4    SPACE          4 < 0x20    PASS/CONTINUE      1\n\0
5       5    1              1 < 0x31    PASS/CONTINUE     1\n\0
6       6    \n             6 < 0x0A    PASS/CONTINUE     \n\0
7       7    \0             7 < 0x00    FAIL/DONE         \0
What about this flow do you not understand?

Perhaps explain for me how "you" would think about single stepping through that for loop as it looks at and processes "line 1\n\0"

Last edited by rtmistler; 10-28-2019 at 10:26 AM.
 
1 members found this post helpful.
  


Reply

Tags
fgets, strings



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
LXer: Tabs or spaces? Spaces, obviously, but how many? LXer Syndicated Linux News 0 09-13-2018 09:50 AM
block special and character special files s_shenbaga Linux - Newbie 4 06-23-2015 02:16 AM
LXer: Special mention for Special purpose LXer Syndicated Linux News 0 04-22-2011 11:11 AM
renaming files with spaces and special characters. bowens44 Linux - Newbie 8 06-29-2009 06:52 PM
Spaces and escaped spaces pslacerda Linux - Newbie 13 12-20-2008 09:03 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 03:46 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration