Reverse Each Specific Line in a String - c

I am attempting to reverse my lines within a text file using the recursion method. I am pretty stuck right now and my current output is a Segmentation Error- Can someone explain what the segmentation error is from and push me in the right direction?
void RecursionLine();
int main (int argc, char argv)
{
RecursionLine();
printf("\n");
}
void RecursionLine()
{
int c;
if((c = getchar()) != EOF || (c != '\n'))
{
RecursionLine();
printf("%c",c);
}
else if((c = getchar()) != EOF && (c == '\n')){
printf("\n");
RecursionLine();
}
}
Input:
Dogs
Cats
Boys
Output
sgoD
staC
syoB

You are getting a Segmentation error because you have an || condition in your first if statement, where one of those conditions will always be true, causing your stack to overflow from infinite recursion! Change this to an && and it should be all fixed!
if((c = getchar()) != EOF && (c != '\n'))
EDIT: Additionally I believe you are going to run into some improper functionality due to the second getchar(). I would change your function to:
void RecursionLine()
{
int c = getchar();
if(c != EOF || c != '\n')
{
RecursionLine();
printf("%c",c);
}
else if(c != EOF && c == '\n'){
printf("\n");
RecursionLine();
}
}
Otherwise you are going to read in potentially 2 characters every iteration and that is going to cause one/both of them to be skipped!

Related

reading a file using getc and skipping a line if it starts with semicolon

while((c = getc(file)) != -1)
{
if (c == ';')
{
//here I want to skip the line that starts with ;
//I don't want to read any more characters on this line
}
else
{
do
{
//Here I do my stuff
}while (c != -1 && c != '\n');//until end of file
}
}
Can I completely skip a line using getc if first character of line is a semicolon?
Your code contains a couple of references to -1. I suspect that you're assuming that EOF is -1. That's a common value, but it is simply required to be a negative value — any negative value that will fit in an int. Do not get into bad habits at the start of your career. Write EOF where you are checking for EOF (and don't write EOF where you are checking for -1).
int c;
while ((c = getc(file)) != EOF)
{
if (c == ';')
{
// Gobble the rest of the line, or up until EOF
while ((c = getc(file)) != EOF && c != '\n')
;
}
else
{
do
{
//Here I do my stuff
…
} while ((c = getc(file)) != EOF && c != '\n');
}
}
Note that getc() returns an int so c is declared as an int.
Let's assume that by "line" you mean a string of characters until you hit a designated end-of-line character (here assumed as \n, different systems use different characters or character sequences like \r\n). Then whether the current character c is in a semicolon-started line or not becomes a state information which you need to maintain across different iterations of the while-loop. For example:
bool is_new_line = true;
bool starts_with_semicolon = false;
int c;
while ((c = getc(file) != EOF) {
if (is_new_line) {
starts_with_semicolon = c == ';';
}
if (!starts_with_semicolon) {
// Process the character.
}
// If c is '\n', then next letter starts a new line.
is_new_line = c == '\n';
}
The code is just to illustrate the principle -- it's not tested or anything.

Why they have to be on the same line: (c = getchar()) != EOF)

I don't understand.
I try to write a program to eliminate white spaces:
int c;
c = getchar();
while (c!= EOF) {
//do things
}
The above code causes a lot of the first input characters to output to screen,
yet
while ((c = getchar()) != EOF)
solved the problem.
Why?
How do I debug to understand this better?
while ((c = getchar()) != EOF)
solved the problem
Because your are calling getchar() on each iteration, and in the first code you wasn't.
Try this
#include <ctype.h>
#include <stdio.h>
void removeSpaces()
{
do {
chr = getchar();
} while ((chr != EOF) && (isspace(chr) != 0));
}
then just call removeSpaces() whenever you want to remove spaces.

Why is this program yielding wrong output

This program is supposed to remove all comments from a C source code (in this case comments are considered double slashes '//' and a newline character '\n' and anything in between them, and also anything between '/* ' and '*/'.
The program:
#include <stdio.h>
/* This is a multi line comment
testing */
int main() {
int c;
while ((c = getchar()) != EOF)
{
if (c == '/') //Possible comment
{
c = getchar();
if (c == '/') // Single line comment
while (c = getchar()) //While there is a character and is not EOF
if (c == '\n') //If a space character is found, end of comment reached, end loop
break;
else if (c == '*') //Multi line comment
{
while (c = getchar()) //While there is a character and it is not EOF
{
if (c == '*' && getchar() == '/') //If c equals '*' and the next character equals '/', end of comment reached, end loop
break;
}
}
else putchar('/'); putchar(c); //If not comment, print '/' and the character next to it
}
else putchar(c); //if not comment, print character
}
}
After I use this source code as its own input, this is the output I get:
#include <stdio.h>
* This is a multi line comment
testing *
int main() {
int c;
while ((c = getchar()) != EOF)
{
if (c == '') ////////////////
{
c = getchar();
if (c == '') ////////////////////
while (c = getchar()) /////////////////////////////////////////
if (c == '\n') ///////////////////////////////////////////////////////////////
break;
else if (c == '*') ///////////////////
{
while (c = getchar()) ////////////////////////////////////////////
{
No more beyond this point. I'm compiling it using g++ on the ubuntu terminal.
As you can see, multi lines comments had only their '/' characters removed, while single line ones, had all their characters replaced by '/'. Apart from that, any '/' characters that were NOT the beginning of a new comment were also removed, as in the line if (c == ''), which was supposed to be if (c == '/').
Does anybody know why? thanks.
C does not take notice of the way you indent your code. It only cares about its own grammar.
Look carefully at your elses and think about which if they attach to (hint: the closest open one).
There are other bugs, as well. EOF is not 0, so only the first while is correct. And what happens if the comment looks like this: /* something **/?
You have some (apparent) logic errors...
1.
while (c = getchar()) //While there is a character and is not EOF
You're assuming that EOF == 0. Why not be explicit and change the preceding line to:
while((c = getchar()) != EOF)
2.
else putchar('/'); putchar(c);
Are both of the putchars supposed to be part of the else clause? If so, you need braces {} around the two putchar statements. Also, give each putchar its own line; it not only looks nicer but it's more readable.
Conclusion
Other than what I've mentioned, your logic looks sound.
As already mentioned, the if/else matching is incorrect. One aditional missing functionality is that you must make it more stateful to keep track of whether you are inside a string or not, e.g.
printf("This is not // a comment\n");

K&R answer 1-12 (using functions to reduce the number of lines of code)

I have written the following program to answer Kernighan and Ritchies ch1 problem 12.
The issue is that I have never really understood how to properly use functions and would like to know why the one I wrote into this program, getcharc(), does not work?
What are good resources that explain correct function usage. Where? and How?
I know the optimal solution to this problem from Richard Heathfield's site (which uses || or, rather than nested while statements, which I have used), however I would like to know how to make my program work properly:
#include <stdio.h>
int getcharc ();
// Exercise 1-12
// Copy input to output, one word per line
// words deleniated by tab, backspace, \ and space
int main()
{
int c;
while ((c = getchar()) != EOF) {
while ( c == '\t') {
getcharc(c);
}
while ( c == '\b') {
getcharc(c);
}
while ( c == '\\') {
getcharc(c);
}
while ( c == ' ') {
getcharc(c);
}
putchar(c);
}
}
int getcharc ()
{
int c;
c = getchar();
printf("\n");
return 0;
}
The original program (and I know it has bugs), without the function was:
#include <stdio.h>
// Exercise 1-12
// Copy input to output, one word per line
// words deleniated by tab, backspace, \ and space
int main()
{
int c;
while ((c = getchar()) != EOF) {
while ( c == '\t') {
c = getchar();
printf("\n");
}
while ( c == '\b') {
c = getchar();
printf("\n");
}
while ( c == '\\') {
c = getchar();
printf("\n");
}
while ( c == ' ') {
c = getchar();
printf("\n");
}
putchar(c);
}
}
So all I am trying to do with the function is to stop
c = getchar();
printf("\n");
being repeated every time.
What, exactly, is this getcharc() function supposed to do? What it does, is read a character from input, print a newline, and return zero. The character just read from input is discarded, because you didn't do anything with it. When it's called, the return value is ignored as well. In each of the places where it is called, you're calling it in an infinite loop, because there's no provision made for changing the loop control variable.
Perhaps you were intending something like c = getcharc(), but that wouldn't really help because you aren't returning c from the function, anyway. (Well, it would help with the "infinite loop" part, anyway.)
What's the point of this function anyway? If you just use getchar() correctly in its place, it looks like you'd have your solution, barring a few other bugs.
One of the possible solution is, change prototype for your function to int getcharc (int c, int flag).
Now your code after some modification;
#include <stdio.h>
int getcharc (int c, int flag);
// Exercise 1-12
// Copy input to output, one word per line
// words deleniated by tab, backspace, \ and space
int main()
{
int c;
int flag = 0; //to keep track of repeated newline chars.
while ((c = getchar()) != '\n') {
flag = getcharc(c, flag); // call getcharc() for each char in the input string. Testing for newline and printing of chars be done in the getcharc() function
}
return 0;
}
int getcharc (int c, int flag)
{
if( (c == ' ' || c == '\t' || c == '\b' || c== '\\') && flag == 0)
{
printf("\n");
flag = 1;
}
else
{
if(c != ' ' && c != '\t' && c != '\b' && c!= '\\')
{
putchar(c);
flag = 0;
}
}
return flag;
}
EDIT:
but I wanted to keep the nested while statements rather than using || or
Your nested while loop is executing only once for each character as grtchar() reads one character at one time. No need of nested loops here! You can check it by replacing while to if and your code will give the same output for a given string. See the output here.
know the optimal solution to this problem from Richard Heathfield's site (which uses || or, rather than nested while statements, which I have used), however I would like to know how to make my program work properly:
You make your program work to some extent (with your bugs) by adding an if condition and a break statement as;
#include <stdio.h>
int getcharc (int c);
int main()
{
int c;
while ((c = getchar()) != '\n') {
while ( c == '\t') {
c = getcharc(c);
if(c != '\t')
break;
}
....
....
while ( c == ' ') {
c = getcharc(c);
if(c != ' ')
break;
}
putchar(c);
}
return 0;
}
int getcharc (int c)
{
c = getchar();
printf("\n");
return c;
}
// compiled by my brain muhahaha
#include <stdio.h>
int getcharc(); // we prototype getcharc without an argument
int main()
{
int c; // we declare c
// read character from stdio, if end of file quit, store read character in c
while ((c = getchar()) != EOF) {
// if c is tab \t call function getcharc() until forever since c never changes
while ( c == '\t') {
getcharc(c); // we call function getcharc with an argument
// however getcharc doesn't take an argument according to the prototype
}
// if c is \b call function getcharc() until forever since c never changes
while ( c == '\b') {
getcharc(c);
}
// if c is \\ call function getcharc() until forever since c never changes
while ( c == '\\') {
getcharc(c);
}
// if c is ' ' call function getcharc() until forever since c never changes
while ( c == ' ') {
getcharc(c);
}
// since we never will get here but if we happened to get here by some
// strange influence of some rare cosmic phenomena print out c
putchar(c);
}
}
// getcharc doesn't take an argument
int getcharc ()
{
int c; // we declare another c
c = getchar(); // we read from the keyboard a character
printf("\n"); // we print a newline
return 0; // we return 0 which anyway will never be read by anyone
}
maybe you are getting confused with the old K&R
nowadays when you write a function argument you specify it like
int getcharch(int c)
{
...
}

How to exit a while-loop?

#include <stdio.h>
main(void) {
char ch;
while (1) {
if ((ch = getchar()) != EOF)
{
break;
}
putchar(ch);
}
return 0;
}
How do I escape from this while? I had tried with EOF but it didn't work.
I think you mean:
int ch;
Because EOF won't fit in a char.
Also:
if ((ch=getchar()) == EOF)
break;
Your logic is backwards.
This:
char ch;
is wrong, EOF doesn't fit in a char. The type of getchar()'s return value is int so this code should be:
int ch;
Also, as pointed out, your logic is backwards. It loop while ch is not EOF, so you can just put it in the while:
while((ch = getchar()) != EOF)
check with the while. It's more simple
while((ch=getchar())!= EOF) {
putchar(ch);
}
The EOF is used to indicate the end of a file. If you are reading character from stdin, You can stop this while loop by entering:
EOF = CTRL + D (for Linux)
EOF = CTRL + Z (for Windows)
You can make your check also with Escape chracter or \n charcter
Example
while((ch=getchar()) != 0x1b) { // 0x1b is the ascii of ESC
putchar(ch);
}

Resources