C Program, Nothing printing in terminal - c

I have the following c program that should print our a vertical histogram of the lengths of the words in its input.
#include <stdio.h>
#define MAX_WORD_LENGTH 35 /* maximum word length we will support */
int main(void)
{
int i, j; /* counters */
int c; /* current character in input */
int length; /* length of the current word */
int lengths[MAX_WORD_LENGTH]; /* one for each possible histogram bar */
int overlong_words; /* number of words that were too long */
for (i = 0; i < MAX_WORD_LENGTH; ++i)
lengths[i] = 0;
overlong_words = 0;
while((c = getchar()) != EOF)
if (c == ' ' || c == '\t' || c == '\n')
while ((c = getchar()) && c == ' ' || c == '\t' || c == '\n')
;
else {
length = 1;
while ((c = getchar()) && c != ' ' && c != '\t' && c != '\n')
++length;
if (length < MAX_WORD_LENGTH)
++lengths[length];
else
++overlong_words;
}
printf("Histogram by Word Lengths\n");
printf("=========================\n");
for (i = 0; i < MAX_WORD_LENGTH; ++i) {
if (lengths[i] != 0) {
printf("%2d ", i);
for (j = 0; j < lengths[i]; ++j)
putchar('#');
putchar('\n');
}
}
}
I have this compiled as a.out, at the terminal I do ./a.out, I type in a word and nothing happens. Any help? I am new to C and just trying to learn.

Your program doesn't print anything out until after getchar() returns EOF. That means entering a word and hitting return won't do it. You need to press ^D on a blank line to tell your terminal emulator to close the input stream.
A quick test here seems to show that your program works. You may want to check on the order of operations in your big &&/|| logic - clang gave me some warnings about && within ||.

Related

When reusing character array I always get extra letter of previous value in the end

I am toying around with C language and I wanted to see how exactly null character \0 works. I have a character array initialized to length of 1000. I read text stream with getchar and place the characters into the array by iterating over the whole length of the array (1000).
After the loop I add null character to the end of stored characters. After this, I repeat the exact thing for second time. However when I print out the characters for 2nd time, I always get extra letter in the output.
STDIN input: aa
output aa
STDIN input b
output ba (I would expect it to be just b)
This is the code:
#include <stdio.h>
#define MAX 1000
int main() {
char line[MAX];
int i;
int c;
for (i = 0; (c = getchar()) != EOF && c != '\n' && i < MAX - 1; ++i) {
line[i] = c;
}
++i;
line[i] = '\0';
printf("%s\n", line);
for (i = 0; (c = getchar()) != EOF && c != '\n' && i < MAX - 1; ++i) {
line[i] = c;
}
++i;
line[i] = '\0';
printf("%s\n", line);
}
You are placing 0 one character too far.
for loop advanced the last char (to be populated in a loop). the line[i] is where that 0 should go. Remove ++i.
You're using pre-increment and i value get increased, Just remove ++i before assigning '\0'
Try this:
#define MAX 1000
int main() {
char line[MAX];
int i;
int c;
for (i = 0; (c = getchar()) != EOF && c != '\n' && i < MAX - 1; ++i) {
line[i] = c;
}
line[i] = '\0';
printf("%s\n", line);
for (i = 0; (c = getchar()) != EOF && c != '\n' && i < MAX - 1; ++i) {
line[i] = c;
}
line[i] = '\0';
printf("%s\n", line);
}
When you end a for loop as the ones you have written, you must think that i gets incremented just before the test that makes you to get out of the loop, so i actually points to the next character position.
This makes your lines
++i;
unnecessary, and you should just say:
line[i] = '\0';

I have encountered segmentation error when attempting to replace the tabs from entered strings with spaces

I have experienced some problem with segmentation when I'm learning through C, my aim is to swap the tabs in the program with spaces:
I have used the get_line template and modified the code to suit the situation. Here is the whole coded solution:
#include <stdio.h>
#define MAXLINE 1000
char line[MAXLINE];
char detabline[MAXLINE];
int get_line(void);
int main(void){
int len;
int i;
int nt = 0;
extern char detabline[];
extern char line[];
while ((len = get_line()) > 0){
for (i = 0; i < len; ++i){
if (line[i] == '\t'){
printf("%s", " ");
}
else{
printf("%s", line[i]);
}
}
}
return 0;
}
int get_line(void){
int c, i, nt;
nt = 0;
extern char line[];
for (i = 0; i < (MAXLINE - 1) && (c = getchar()) != EOF && ((c != '\t') || (c != '\n')); ++i){
line[i] = c;
}
if (c == '\n'){
line[i] = c;
++i;
}
else if (c == '\t'){
++nt;
}
line[i] = '\0';
return i;
}
The problem is to locate which memory isn't allocated correctly. I may have some redundant code in the solution by the way.
regarding:
for (i = 0; i < (MAXLINE - 1) && (c = getchar()) != EOF && ((c != '\t') || (c != '\n')); ++i){
this expression:
(c != '\t')
will result in no tab character ever being in the line[] array.
this expression:
(c != '\n')
will result in no newline character sequence ever being in the line[] array.
then, due those expressions, the line[] array will not be updated (ever again) when a tab or a newline is encountered due to those expressions causing an early exit from the for() loop
The following proposed code:
cleanly compiles
performs the desired functionality
and now, the proposed code:
#include <stdio.h>
#define MAXLINE 1000
char line[MAXLINE];
int main(void)
{
int i = 0;
int ch;
while ( i< MAXLINE-1 && (ch = getchar()) != EOF && ch != '\n' )
{
if ( ch == '\t')
{
line[i] = ' ';
}
else
{
line[i] = (char)ch;
}
i++;
}
printf( "%s\n", line );
}
Post a comment if you want further details about the proposed code.

Getc() reading \n improperly

I am creating a program that prints each line of a file one by one in reverse word order. i.e. "The big black moose" prints as "moose black big The".
However, in the code below, it does not print the last word of lines that do not have a delimiter before the line break. A delimiter in this case is defined as any whitespace character such as space or tab.
int main(int argc, char const *argv[]) {
if (argc != 2) return 0;
int i = 0, c;
int isD = 0, wasD = 1;
int count = 0;
FILE *file = fopen(argv[1], "r");
while ((c = getc(file)) != EOF) {
isD = c == ' ' || c == '\t' || c == '\n';
if (!isD) {
chars[i++] = c;
count++;
}
if (isD && !wasD) {
shiftInsert(i++, count);
count = 0;
}
wasD = isD;
}
fclose(file);
return 0;
}
int shiftInsert(int length, int shift) {
int word[shift+1], i;
printf("\n----------\nL:%d,S:%d\n", length, shift);
for (i = 0; i < shift; i++)
word[i] = chars[length-shift+i];
word[shift] = ' ';
for (i = 0; i < shift; i++)
printf("%c", word[i]);
for (i = length; i >= 0; i--)
chars[i+shift+1] = chars[i];
for (i = 0; i <= shift; i++)
chars[i] = word[i];
printf("|");
}
This happens, because you don't enter the loop when getc finds the end of the file. If wasD is false, you'll have one unprocessed word in the buffer.
You could treat EOF as whitespace and place the terminating condition at the end of the loop:
do {
c = getc(file);
isD = (c == ' ' || c == '\t' || c == '\n' || c == EOF);
// ...
} while (c != EOF);
This works, because you use the value of c only if it is not a delimiter. (The special value EOF is outside the valid range of (unsigned) chars and should not be inserted into strings or printed.)
stdout is not getting flushed because your last output didn't contain a newline...
Change this line
printf("|");
to
printf("|\n");

K&R Exercise 4-3

I just solved the exercise 4-10 - I replaced (unget/get)char with getline, but I can't add support for negative numbers. The reasoning is simple, if a char is a '-' and the character next to it is a digit or a decimal point we have a negative number. I don't know what I did wrong, first time i tryed something like this:
if(c != '-' && isdigit(line[lp])) {
return c;
}
If we have a negative number, line 2 shouldn't be executed, and the array s will have as the first element a '-'. However, I get an infinite loop and i can't find the problem.
This is the most relevant piece of code for this problem(especially the 4th if statement in getop).
#define MAXLINE 100
char line[MAXLINE];
int lp = 0;
int lineLength = 0;
int getline(char s[], int lim) {
int i, c;
i = 0;
while(--lim > 0 && (c = getchar()) != EOF && c != '\n')
s[i++] = c;
if(c == '\n')
s[i++] = c;
s[i] = '\0';
return i;
}
int getop(char s[]) {
if(lp == lineLength) {
lineLength = getline(line, MAXLINE);
lp = 0;
}
if(lineLength == 0)
return EOF;
char c;
int i;
printf("the execution is here\n");
while((s[0] = c = line[lp++]) == ' ' || c == '\t')
/* skip tabs an white spaces */;
s[1] = '\0';
if(!isdigit(c) && c != '.' && c != '-')
return c;
if(c == '-') {
if(isdigit(line[lp]) || line[lp] == '.')
/* nothing */;
else
return c;
}
i = 0;
if(isdigit(c))
while(isdigit((s[++i] = c = line[lp++])))
;
if(c == '.')
while(isdigit((s[++i] = c = line[lp++])))
;
lp--;
return NUMBER;
}
You need to advance lp when you find a '-'. The if's at the bottom of the function don't look for '-'. You'll notice other digits (and the decimal point) advances lp before the function returns, so you need to copy that '-' sign to s[] (or store it in global flag) and increment lp, otherwise it just processes the same character over and over.
Stepping through the code in a debugger would help you see the problem as well, if you look at what lp does for positive numbers vs. negative numbers.

Histogram of the length of words exercise hint?

I'm learning C with "The C Programming Language" book, and I'm trying to solve exercise 1.13:
"Write a program to print a histogram of the lengths of words in its input. It is easy to
draw the histogram with the bars horizontal; a vertical orientation is more challenging."
I wrote the code, but when I press CTRL+Z (End-of-File), it shows all zeros instead of the length of words.
Could anyone give me a hint on where I'm going wrong?
#include <stdio.h>
/* print a histogram of the length of words from input */
main()
{
int c, i, wordn, space;
int lengthn[20];
wordn = space = 0;
for (i = 0; i < 20; ++i)
lengthn[i] = 0;
while ((c = getchar()) != EOF) {
if (c == ' ' || c == '\t' || c == '\n')
if (space == 1) {
++wordn;
space = 0;
++i;
}
if (c != ' ' && c != '\t' && c != '\n') {
++lengthn[i];
space = 1;
}
}
printf("Length: ");
for (i = 0; i < 16; ++i)
printf("%d ", lengthn[i]);
printf("\n --------------------------------------------------------------\n");
printf("Word: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15\n");
}
(Because the OP is asking for hints, not the solution)
So ... what does i equal after this loop?
for (i = 0; i < 20; ++i)
lengthn[i] = 0;
And where do you use it next?
for (i = 0; i < 20; ++i)
lengthn[i] = 0;
The value of i after this loop will be i=20
so you must initialize i before while loop
I wrote a code for the vertical orientation.
I'm new to C, so may be the code is not good.
#include <stdio.h>
#include <conio.h>
#define MAX_WORDS 100
#define IN 1
#define OUT 0
int maxlength(int length[], char num_of_word);
int main()
{
char c,i,j,state,num_of_word;
int length[MAX_WORDS];
/*initialize length[]*/
for(i=0;i<MAX_WORDS;i++){
length[i]=0;
}
/* find the length of each word */
num_of_word=0;
while(num_of_word<MAX_WORDS && (c = getchar()) != EOF && c != 'a'){
if(c != ' ' && c!= '\t' && c!= '\n'){
state = IN;
length[num_of_word]++;
}else{
if(state != OUT){
state = OUT;
num_of_word++;
}
}
}
/* draw histogram */
for(i= maxlength(length[],num_of_word);i>0;i--){
for(j=0;j<num_of_word;j++){
if(length[j]<i){
printf(" ");
}else{
printf("|");
}
}
printf("\n");
}
/* print name of each column*/
for(i=0;i<num_of_word;i++){
printf("%d",i+1);
}
_getch();
return(0);
}
/*sub-function that find the longest word */
int maxlength(int length[], char num_of_word){
int i, max;
max = length[0];
for(i=1;i<num_of_word;i++){
if(max<length[i]){
max = length[i];
}
}
return max;
}

Resources