LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
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 09-06-2020, 09:31 AM   #1
Arct1c_f0x
Member
 
Registered: Feb 2020
Posts: 82

Rep: Reputation: Disabled
Exercise 1-22 in the K&R. What error is responsible?


Code:
// This program is specified by Exercise 1-22 of the K&R Ansi edition
/* Exercise 1-22. Write a program to ``fold'' long input lines into two or more shorter lines after
the last non-blank character that occurs before the n-th column of input. Make sure your
program does something intelligent with very long lines, and if there are no blanks or tabs
before the specified column. */

#include <stdio.h>

#define MAXINPUTLINELEN 80
int c, i;
char CurrenInputLine[500];


int main() {
i = 0;

while ((c = getchar() != EOF) || ((c=getchar()) != '\n')) {
     CurrenInputLine[i] = c;

     if (i % MAXINPUTLINELEN == 0) {
         if (CurrenInputLine[i] == ' ' || CurrenInputLine[i] == '\t') {
         ++i;
         CurrenInputLine[i] = '\n';}
         else if (CurrenInputLine[i] != ' ' || CurrenInputLine[i] == '\t') {
             while ((c = getchar()) != EOF) {
                if (c != ' ' || c != '\t') {
                CurrenInputLine[i] = c;
                ++i;}
                else if (c == ' ' || c == '\t') {
                    CurrenInputLine[i] = c;
                    ++i;
                    CurrenInputLine[i] = '\n';
                    break;
                }

             }
                }

     }
     
     ++i;
}
++i;
CurrenInputLine[i] = '\0';
printf("%s", CurrenInputLine);
}

in std output it says: "Segmentation fault (core dumped)" which I understand has to do with the program's access to the memory that it's creating. What am I doing wrong?

My humble gratitude,
 
Old 09-06-2020, 05:02 PM   #2
astrogeek
Moderator
 
Registered: Oct 2008
Distribution: Slackware [64]-X.{0|1|2|37|-current} ::12<=X<=14, FreeBSD_12{.0|.1}
Posts: 5,434
Blog Entries: 11

Rep: Reputation: 3398Reputation: 3398Reputation: 3398Reputation: 3398Reputation: 3398Reputation: 3398Reputation: 3398Reputation: 3398Reputation: 3398Reputation: 3398Reputation: 3398
On first look I think your outer while loop condition is not what you want.

Code:
while ((c = getchar() != EOF) || ((c=getchar()) != '\n')) { ... }
I think you want to read one character per loop pass, exit loop on EOF and handle newlines within the loop.

That won't likely fix the segmentation fault, but verify your loop control is right first, then fix internal problems.

Last edited by astrogeek; 09-06-2020 at 09:20 PM.
 
1 members found this post helpful.
Old 09-06-2020, 08:46 PM   #3
rtmistler
Moderator
 
Registered: Mar 2011
Location: USA
Distribution: MINT Debian, Angstrom, SUSE, Ubuntu, Debian
Posts: 8,907
Blog Entries: 13

Rep: Reputation: 4040Reputation: 4040Reputation: 4040Reputation: 4040Reputation: 4040Reputation: 4040Reputation: 4040Reputation: 4040Reputation: 4040Reputation: 4040Reputation: 4040
Did you debug this?

See the blog in my signature, specifically about how to analyze core faults using GDB.
 
1 members found this post helpful.
Old 09-07-2020, 04:47 AM   #4
GazL
LQ Guru
 
Registered: May 2008
Distribution: CRUX
Posts: 5,547
Blog Entries: 14

Rep: Reputation: 3387Reputation: 3387Reputation: 3387Reputation: 3387Reputation: 3387Reputation: 3387Reputation: 3387Reputation: 3387Reputation: 3387Reputation: 3387Reputation: 3387
Quote:
/* Exercise 1-22. Write a program to ``fold'' long input lines into two or more shorter lines after the last non-blank character that occurs before the n-th column of input. Make sure your program does something intelligent with very long lines, and if there are no blanks or tabs before the specified column. */
I never liked the wording of this exercise. The second sentence suggests to me that the goal is to implement some sort of word-wrap at the n-th column, but as written, if the n-th column is in the middle of a word then "the last non-blank character before the n-th column" will also be in a word (i.e. it'll be at n-1), and the word will be split.

"after the last blank character before" seems clearer, but maybe "after the last non-blank to blank character transition before..." is a better way of phrasing it.

But, maybe this is asking for something other than word-wrap, and I've got the wrong end of the stick. Either way, I find the phrasing annoyingly confusing.


As for the code posted:
( x != y || x != z ) in conditional logic should always be treated with suspicion, because when y != z, it will always evaluate true.

Last edited by GazL; 09-07-2020 at 04:51 AM.
 
Old 09-07-2020, 06:16 AM   #5
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,075

Rep: Reputation: 1475Reputation: 1475Reputation: 1475Reputation: 1475Reputation: 1475Reputation: 1475Reputation: 1475Reputation: 1475Reputation: 1475Reputation: 1475
@OP: I think first you should invent an algorithm, and start programming only afterwards.
Some hints: the solution should be a single loop that contains an if-ladder, e.g.:
Code:
while ((c=getchar())!=EOF) {
    buff[cnt++]= c;
    if (c==' ') do something;
    else if (c=='\n') do sg else;
    if (cnt==MAXLEN) {
        buffer is full, flush part/all of it
    }
}
 
Old 09-07-2020, 11:04 AM   #6
Arct1c_f0x
Member
 
Registered: Feb 2020
Posts: 82

Original Poster
Rep: Reputation: Disabled
Quote:
Originally Posted by rtmistler View Post
Did you debug this?

See the blog in my signature, specifically about how to analyze core faults using GDB.
Yes. I need to learn how to use GDB, I've just been putting it off but thanks, man and I'm going to set aside a couple hours of time in the next several days in order to read your post. Again, thank you.

Last edited by Arct1c_f0x; 09-07-2020 at 11:11 AM.
 
Old 09-07-2020, 11:06 AM   #7
Arct1c_f0x
Member
 
Registered: Feb 2020
Posts: 82

Original Poster
Rep: Reputation: Disabled
Quote:
Originally Posted by astrogeek View Post
On first look I think your outer while loop condition is not what you want.

Code:
while ((c = getchar() != EOF) || ((c=getchar()) != '\n')) { ... }
I think you want to read one character per loop pass, exit loop on EOF and handle newlines within the loop.

That won't likely fix the segmentation fault, but verify your loop control is right first, then fix internal problems.
Excellent suggestion. It was silly of me to do it otherwise. I implemented that adjustment and it's already running almost correctly.
I'm still a beginner with writing C so I've made some silly mistakes.

Last edited by Arct1c_f0x; 09-07-2020 at 11:11 AM.
 
Old 09-07-2020, 11:10 AM   #8
Arct1c_f0x
Member
 
Registered: Feb 2020
Posts: 82

Original Poster
Rep: Reputation: Disabled
Quote:
Originally Posted by GazL View Post
As for the code posted:
( x != y || x != z ) in conditional logic should always be treated with suspicion, because when y != z, it will always evaluate true.
Really?? Why is that exactly?? I feel like I should have known that. It doesn't seem to make sense to me because the statement (at least in my mind) is:
If x is not equal to y OR x is not equal to z then evaluate as True (but otherwise this is a completely false statement).
 
Old 09-07-2020, 11:20 AM   #9
pan64
LQ Guru
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 15,097

Rep: Reputation: 4972Reputation: 4972Reputation: 4972Reputation: 4972Reputation: 4972Reputation: 4972Reputation: 4972Reputation: 4972Reputation: 4972Reputation: 4972Reputation: 4972
1. you can use valgrind (for example) to catch a segfault.
2. if y!=z then x cannot be equal to both y and z therefore either x!=y or x!=z is true so the final result must be true.
 
2 members found this post helpful.
Old 09-11-2020, 07:37 AM   #10
Arct1c_f0x
Member
 
Registered: Feb 2020
Posts: 82

Original Poster
Rep: Reputation: Disabled
Exclamation

Quote:
Originally Posted by rtmistler View Post
Did you debug this?

See the blog in my signature, specifically about how to analyze core faults using GDB.
Thanks !

Read your blog post on using GDB (by itself) and GDB through the Gnu emacs utility. I really like using GDB through emacs; that interface is very helpful. Thanks again.
 
Old 09-11-2020, 09:15 AM   #11
rtmistler
Moderator
 
Registered: Mar 2011
Location: USA
Distribution: MINT Debian, Angstrom, SUSE, Ubuntu, Debian
Posts: 8,907
Blog Entries: 13

Rep: Reputation: 4040Reputation: 4040Reputation: 4040Reputation: 4040Reputation: 4040Reputation: 4040Reputation: 4040Reputation: 4040Reputation: 4040Reputation: 4040Reputation: 4040
Quote:
Originally Posted by Arct1c_f0x View Post
Quote:
Originally Posted by GazL View Post
As for the code posted:
( x != y || x != z ) in conditional logic should always be treated with suspicion, because when y != z, it will always evaluate true.
Really?? Why is that exactly?? I feel like I should have known that. It doesn't seem to make sense to me because the statement (at least in my mind) is:
If x is not equal to y OR x is not equal to z then evaluate as True (but otherwise this is a completely false statement).
I have to be honest here and say that I do not expend effort to continually figure out precedence. I always use parentheses to be 100% clear of my intentions.
Quote:
Originally Posted by Arct1c_f0x View Post
Thanks !

Read your blog post on using GDB (by itself) and GDB through the Gnu emacs utility. I really like using GDB through emacs; that interface is very helpful. Thanks again.
I'm sure there are plenty of guides available, but glad you enjoyed the one written. Did you use it to benefit and resolve your segmentation fault, or to diagnose your project? There are many ways to debug, such as printing progressive outputs through a program to determine how far it got and then center to a point of probable fault, or to use a debugger like GDB. It's not clear yet how far you've gotten with diagnosing your code.
 
Old 09-11-2020, 11:34 AM   #12
GazL
LQ Guru
 
Registered: May 2008
Distribution: CRUX
Posts: 5,547
Blog Entries: 14

Rep: Reputation: 3387Reputation: 3387Reputation: 3387Reputation: 3387Reputation: 3387Reputation: 3387Reputation: 3387Reputation: 3387Reputation: 3387Reputation: 3387Reputation: 3387
Quote:
Originally Posted by rtmistler View Post
I have to be honest here and say that I do not expend effort to continually figure out precedence.
Yep, I often do that too: if only to make gcc shut-up with the warnings!

It wasn't really an operator precedence issue. I won't go over it again as pan already expanded on my comment, but additional parenthesis wouldn't help in this case: it's just what happens when you use two non-equality tests on the same variable with an 'or'.
 
Old 09-12-2020, 07:40 AM   #13
Arct1c_f0x
Member
 
Registered: Feb 2020
Posts: 82

Original Poster
Rep: Reputation: Disabled
Quote:
Originally Posted by GazL View Post
Yep, I often do that too: if only to make gcc shut-up with the warnings!

It wasn't really an operator precedence issue. I won't go over it again as pan already expanded on my comment, but additional parenthesis wouldn't help in this case: it's just what happens when you use two non-equality tests on the same variable with an 'or'.
It totally makes sense to me now but it didn't before for some reason.
 
Old 09-12-2020, 07:42 AM   #14
Arct1c_f0x
Member
 
Registered: Feb 2020
Posts: 82

Original Poster
Rep: Reputation: Disabled
Quote:
Originally Posted by rtmistler View Post
I have to be honest here and say that I do not expend effort to continually figure out precedence. I always use parentheses to be 100% clear of my intentions.I'm sure there are plenty of guides available, but glad you enjoyed the one written. Did you use it to benefit and resolve your segmentation fault, or to diagnose your project? There are many ways to debug, such as printing progressive outputs through a program to determine how far it got and then center to a point of probable fault, or to use a debugger like GDB. It's not clear yet how far you've gotten with diagnosing your code.
So the problem that I'm running into now is using GDB (with emacs or even just by itself) and not being able to accept user input from stdin. I'll keep searching stack exchange and other sites for how to do this but if you know how to accomplish this (and I strongly suspect that you do), it would be a welcomed advancement.
 
Old 09-12-2020, 04:08 PM   #15
astrogeek
Moderator
 
Registered: Oct 2008
Distribution: Slackware [64]-X.{0|1|2|37|-current} ::12<=X<=14, FreeBSD_12{.0|.1}
Posts: 5,434
Blog Entries: 11

Rep: Reputation: 3398Reputation: 3398Reputation: 3398Reputation: 3398Reputation: 3398Reputation: 3398Reputation: 3398Reputation: 3398Reputation: 3398Reputation: 3398Reputation: 3398
Quote:
Originally Posted by Arct1c_f0x View Post
So the problem that I'm running into now is using GDB (with emacs or even just by itself) and not being able to accept user input from stdin. I'll keep searching stack exchange and other sites for how to do this but if you know how to accomplish this (and I strongly suspect that you do), it would be a welcomed advancement.
Do you mean your code does not accept input from stdin, or GDB does not respond to input, or both? Working up a simple minimal example which reproduces the behavior would help others, and yourself, better understand the problem.

While being sufficiently familiar with GDB and Valgrind to be able to easily use them when necessary, I find them more useful as aids in diagnosing more obscure problems in otherwise working programs, than as the first resort when debugging new code that doesn't work.

The most important and most efficient debugging "methods" when writing new code, for myself at least, come from the way I approach the problem. The very first thing I do when writing new code is create a model, or algorithm, for solving the problem at hand. As already mentioned:

Quote:
Originally Posted by NevemTeve View Post
@OP: I think first you should invent an algorithm, and start programming only afterwards.
Said more strongly, NEVER write code until you have a clear model of what it should do and how it should do it!

Then when it comes to writing the code, implement each part of the model incrementally, one at a time, and verify that the resulting code for that specific part does what the model requires it to do. If you see a better way to do some part while writing the code then update the model first and only change the code afterwards!

The model, or algorithm is the specification - without that, what are you writing?!

Debugging each simple piece, one at a time, is much simpler and usually requires little more than a few strategically placed print statements to show you the state of the running process.

Once the pieces are verified and tied together debugging is mostly of the model, not the code! If you find your model or algorithm needs to change, change it first, then modify the code accordingly!

This simple discipline reduces most debugging to the exercise of understanding the problem more clearly and finding typos.

For simplest cases try to put the process into words in comments at top of your source code file, again, before writing any code! For more complex tasks use pencil and paper, black or white board, or computer drawing tools.

Following that discipline I find the need to fall back onto GDB or Valgrind less frequent, and more for analysis than for ordinary debugging.

Many people new to programming, in my opinion, often expect the tools to do the debugging for them, and by focusing on the tools never really learn the basic skills. Avoid that trap! Model, model, model - then write code.
 
1 members found this post helpful.
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

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
[SOLVED] K&R Exercise 1-6: What is this asking me to do? anon033 Programming 5 05-23-2019 06:00 PM
[SOLVED] K&R Exercise 1-4: Help Checking My Math anon033 Programming 18 05-23-2019 05:10 PM
[SOLVED] K&R Exercise 1.10 - A Question About Backspaces killingthemonkey Programming 4 02-04-2017 08:25 PM
Ph&#7909;c h&#7891;i d&#7919; li&#7879;u b&#7883; m&#7845;t???, c&#7913; pollsite General 1 06-27-2005 12:39 PM
Gotta love those &#1649;&#1649;&#1649;&#1649;&#1649;&#1649;&#1649;&# iLLuSionZ Linux - General 5 11-18-2003 07:14 AM

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

All times are GMT -5. The time now is 03:30 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