I am new to C programming and I am currently trying to teach myself how to create a C program that can count words and lines in the input stream and print the two totals to the standard output.
What I am actually trying to do is to have the program count the number of lines and count the number of words depending on the definition of a word in which I feel that I am off.
I want the words to exclude blanks, tabs, newlines, hyphens, or colons. While having the program output the results (words and lines) as decimals.
#include<stdio.h>
int main()
{
int iochar;
int words;
int lines;
printf("Enter something here:\n\n");
while ((iochar = getchar ()) !=EOF)
{
if((iochar == ' ') || (iochar == '\t') || (iochar == '\n'))
putchar(iochar);
}
return 0;
}
Am I totally off on this program?
If your question is how to fix the compile error, that's simple. Add one more closing brace at the end.
But your program will still do only one pass through the loop and will print only one character if and only if the user types a space, tab or newline. No matter what the user types, the program will then terminate. I doubt that's what you wanted.
I suspect this is what you intended:
while ((iochar = getchar ()) !=EOF)
{
if((iochar == ' ') || (iochar == '\t') || (iochar == '\n'))
{
putchar(iochar);
}
}
return 0;
After your "I am trying to have thee numbers be right justified in an 8-column field ..." I cannot understand what you are trying to say :(
int words = 0;
int lines = 0;
char buffer[1024];
while(fgets(buffer, sizeof buffer, stdin))
{
lines++;
if(buffer[0] == '\n')
continue;
char *tmp = buffer-1;
while(tmp = strchr(tmp+1, ' '))
words++;
words++; /* count last word before \0*/
}
printf("lines: %d, words: %d\n", lines, words);
is that what you need/want?
The error message is:
Test.c:20:1: error: expected declaration or statement at end of input
It does not compile because you are missing a }.
Had you properly indented your code, like so, you would have found your mistake:
#include<stdio.h>
int main() {
int iochar;
int words;
int lines;
printf("Enter something here:\n\n");
while ((iochar = getchar ()) !=EOF)
{
if((iochar==' ')||(iochar=='\t')||(iochar=='\n'))
{
putchar(iochar);
iochar = getchar();
}
return 0;
}
Yet another example of the importance of readability :)
Related
started C this semester and struggling to convert knowledge of java into C. The code compiles and runs but not as I want it. The task is to write a code that read a text file line by line (I have a get line function) and outputs new text file keeping line formatting the same (meaning that if original file has 4 line output file has to have 4 line) but deleting trailing characters (space and \t). I've spend enormous amount of time pocking at this thing without success. Any help is appreciated.
hw2_execcise_1. program to remove trailing blanks and tabs from each line of input, and to delete entirely blank lines.
Pseudo::: while (there are lines to read)
find end of line1 (\n)
save length
going from the end of the line towards the beginning
find char that is not either space or tab
and insert \n following found char.
#include <stdio.h>
#define LINELIM 1000
int getLine(char s[], int lim);
int main (void){
int len, i;
char line1[100];
while ((len = getLine(line1, LINELIM)) >0){
for (i=len; i>=0; i--){
if ((line1[i] == ' ') || (line1[i] == '\t')){
line1[i] = '\n';
}
else break;
}
printf(" %s\n", line1);
}
return 0;
}
/*getline: read a line into s, return length*/
int getLine(char s[], int lim){
int c,i;
for (i=0; i<lim-1 && (c=getchar())!= EOF && c!='\n'; ++i)
s[i]=c;
if (c == '\n'){
s[i] = c;
++i;
}
s[i] = '\0';
return i;
}
while ((len = getLine(line1, LINELIM)) >0){
for (i=len-1; i>=0; i--){//-1 for 0 origin
if(line1[i] == ' ' || line1[i] == '\t' || line1[i] == '\n'){//add case of '\n'
line1[i] = '\0';//newline add print part
}
else break;
}
if(line1[0])//not blank line
printf("%s\n", line1);
}
the main logic problem with the code is
1) the getline function is terminating each input line with (either) '\n''\0' or with '\0'
2) the main function is not checking for the newline when it checks for space or tab. I.E. it needs to also check for newline --or-- getline() should not ever include the newline
I need to write a program that prints its input one word per line. Here's what I got so far:
#include <stdio.h>
main(){
int c;
while ((c = getchar()) != EOF){
if (c != ' ' || c!='\n' || c!='\t')
printf("%c", c);
else
printf("\n");
}
}
The logic is pretty simple. I check to see if the input is not a newline, tab or space, and in that case it prints it, otherwise prints a newline.
When I run it, I get results like this:
input--> This is
output--> This is
It prints the whole thing. What goes wrong here?
if (c != ' ' || c!='\n' || c!='\t')
This will never be false.
Perhaps you meant:
if (c != ' ' && c!='\n' && c!='\t')
instead of using printf try putchar, also as per above comments, you should use && instead of ||.
here is my code-
#include<stdio.h>
main()
{
int c, nw; /* nw for word & c for character*/
while ( ( c = getchar() ) != EOF ){
if ( c != ' ' && c != '\n' && c != '\t')
nw = c;
else {
nw = '\n';
}
putchar (nw);
}
}
this code will give you the desired output
you can use if you want the strtok function in string.h library which can cut the input into many words by providing a delimiter.
Here is a perfect code commented which can fit to your needs
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[])
{
char line[1000]=""; // the line that you will enter in the input
printf("Input the line:\n>>");
scanf("%[^\n]",line); // read the line till the you hit enter button
char *p=strtok(line," !#$%&'()*+,-./'"); // cut the line into words
// delimiter here are punctuation characters (blank)!#$%&'()*+,-./'
printf("\nThese are the words written in the line :\n");
printf("----------------------------------------\n");
while (p!=NULL) // a loop to extract the words one by one
{
printf("%s\n",p); // print each word
p=strtok(NULL," !#$%&'()*+,-./'"); // repeat till p is null
}
return 0;
}
If we execute the code above we will get
Input the line:
>>hello every body how are you !
These are the words written in the line :
----------------------------------------
hello
every
body
how
are
you
suggest the code implement a state machine,
where there are two states, in-a-word and not-in-a-word.
Also, there are numerous other characters that could be read
(I.E. ',' '.' '?' etc) that need to be check for.
the general logic:
state = not-in-a-word
output '\n'
get first char
loop until eof
if char is in range a...z or in range A...Z
then
output char
state = in-a-word
else if state == in-a-word
then
output '\n'
state = not-in-a-word
else
do nothing
end if
get next char
end loop
output '\n'
I think the simple solution would be like
#include <stdio.h>
int main(void) {
// your code goes here
int c;
while((c=getchar())!=EOF)
{
if(c==' ' || c=='\t' || c=='\b')
{
printf("\n");
while(c==' ' || c=='\t' || c=='\b')
c=getchar();
}
if(c!=EOF)
putchar(c);
}
return 0;
}
I'm new on here and relatively new to programming logic in general. In an effort to develop my skill I've begun reading this fine piece of literature. I really feel that I am grasping the concepts well but this exercise seems to have caught me off guard. I can produce the program but some of the examples I've seen seem to introduce some concepts not yet covered by the book like the examples here. inspace seems to be serving a function that is more than just a variable created by the programmer.
#include <stdio.h>
int main(void)
{
int c;
int inspace;
inspace = 0;
while((c = getchar()) != EOF)
{
if(c == ' ')
{
if(inspace == 0)
{
inspace = 1;
putchar(c);
}
}
/* We haven't met 'else' yet, so we have to be a little clumsy */
if(c != ' ')
{
inspace = 0;
putchar(c);
}
}
return 0;
}
In the next example, pc seems to be doing something in regards to counting spaces but I'm not sure what.
I managed to create a program that completes this task but it was using only the variable c that I created, thus I understand its purpose.
The objective of this code is copy text and if there is more then one spaces ' ' consecutive print only one space.
Variable inspace is used to keep track of whether last time printed char was scape or non-space.
if inspace is zero means a char was printed that was not space. and
if inspace is one means a last time space was printed.
So if inspace is zero next time scape can be printed on reading a scape, and if inspace is one then next consecutive scape found so not to print space.
See C is current char read. (read comments)
if(c == ' ') // currently space read
{
if(inspace == 0) // last time non-space printed, So space can be print
{
inspace = 1; // printing space so switch inspace 1
putchar(c); // print space
}
}
Next if
if(c != ' ') // A char not space read, its to to print unconditionally
{
inspace = 0; // remember that non-scape print
putchar(c);
}
Took me a while but this is the answer I think.
#include <stdio.h>
main()
{
int c, blank;
blank = 0;
while ((c=getchar()) != EOF){
if (c == ' '){
if (blank == 0){
printf("%c", c);
blank = 1;
}
}
if (c != ' '){
if (blank == 1){
blank = 0;
}
printf("%c", c);
}
}
}
inspace is essentially a variable to indicate you are or are not in the "just seen a space" state. You enter this state after seeing a space, and you exit this state when you see a non-space. You print your input only if you're not in the inspace state, thus you do not print multiple adjacent spaces.
I managed to create a program that completes this task but it was using only the variable c that I created, thus I understand its purpose.
In your program, if the input is "hello world", is that its exact output? The program you posted will output "hello world" (compressing the multiple spaces between the words down to one).
I was also having the same problem but finally got a program that works.
#include<stdio.h>
/* copy input to its output, replacing each
string of one or more blanks by a single blank */
int main()
{
int c, nspace=0;
while((c=getchar()) != EOF){
if(c==' ') ++nspace;
else{
if(nspace >= 1){
printf(" ");
putchar(c);
nspace=0;
}
else
putchar(c);
}
}
}
I tried the below program .
INPUT-: i want help
Desired OUTPUT-:Words=3 Characters=9
But the actual output deviates from the desired.
Can someone tell what is my mistake .
include
void main()
{
int countch=0;
int countwd=1;
printf("Enter your sentence in lowercase: ");
char ch='a';
while(ch!='\r')
{
ch=getche();
if(ch==' ')
countwd++;
else
countch++;
}
printf("\n Words = ",countwd);
printf("Characters = ",countch-1);
getch();
}
Be advised: getchar() returns int, not char. This is one of the most common pitfalls for beginning C programmers, it seems.
Also, you should check for the special value EOF and stop the program if it occurs; this is the typical and "clean" way of doing programs that read input and will make the program automatically handle both interactive input (from a terminal) and input from a file.
There are few observations which you might find of some use:
1. You are using getch & getche which are both non-standard functions. Make use of getchar instead. In this case as already pointed in unwind's response you need to use int for the return type.
2. Please change the return type of main from void to int.
3. You are not specifying the formats in printf. Please add %d specifier to print integers.
I have not used codepad but ideone allows you to add inputs to your programs. Here is a reference based on your sample on ideone.
Hope this helps!
#include<stdio.h>
#include<stdbool.h>
int main(void)
{
char c = '\0';
int nw = 0,nc = 0,nl = 0;
bool flag = true;
bool last = false,cur = false;
while(flag && (c = getchar())) {
if(c != EOF)
++nc;
else
flag = false;
if(c == '\n') nl++;
cur = (c == EOF || c == ' ' || c == '\t' || c == '\n')?false:true;
if(last && !cur )
++nw;
last = cur;
}
printf("\nNo of chars : %d",nc);
printf("\nNo of lines : %d",nl);
printf("\nNo of words : %d",nw);
return 0;
}
EDIT:
complete code with main is here http://codepad.org/79aLzj2H
and once again this is were the weird behavious is happening
for (i = 0; i<tab_size; i++)
{
//CORRECT OUTPUT
printf("%s\n", tableau[i].capitale);
printf("%s\n", tableau[i].pays);
printf("%s\n", tableau[i].commentaire);
//WRONG OUTPUT
//printf("%s --- %s --- %s |\n", tableau[i].capitale, tableau[i].pays, tableau[i].commentaire);
}
I have an array of the following strcuture
struct T_info
{
char capitale[255];
char pays[255];
char commentaire[255];
};
struct T_info *tableau;
This is how the array is populated
int advance(FILE *f)
{
char c;
c = getc(f);
if(c == '\n')
return 0;
while(c != EOF && (c == ' ' || c == '\t'))
{
c = getc(f);
}
return fseek(f, -1, SEEK_CUR);
}
int get_word(FILE *f, char * buffer)
{
char c;
int count = 0;
int space = 0;
while((c = getc(f)) != EOF)
{
if (c == '\n')
{
buffer[count] = '\0';
return -2;
}
if ((c == ' ' || c == '\t') && space < 1)
{
buffer[count] = c;
count ++;
space++;
}
else
{
if (c != ' ' && c != '\t')
{
buffer[count] = c;
count ++;
space = 0;
}
else /* more than one space*/
{
advance(f);
break;
}
}
}
buffer[count] = '\0';
if(c == EOF)
return -1;
return count;
}
void fill_table(FILE *f,struct T_info *tab)
{
int line = 0, column = 0;
fseek(f, 0, SEEK_SET);
char buffer[MAX_LINE];
char c;
int res;
int i = 0;
while((res = get_word(f, buffer)) != -999)
{
switch(column)
{
case 0:
strcpy(tab[line].capitale, buffer);
column++;
break;
case 1:
strcpy(tab[line].pays, buffer);
column++;
break;
default:
strcpy(tab[line].commentaire, buffer);
column++;
break;
}
/*if I printf each one alone here, everything works ok*/
//last word in line
if (res == -2)
{
if (column == 2)
{
strcpy(tab[line].commentaire, " ");
}
//wrong output here
printf("%s -- %s -- %s\n", tab[line].capitale, tab[line].pays, tab[line].commentaire);
column = 0;
line++;
continue;
}
column = column % 3;
if (column == 0)
{
line++;
}
/*EOF reached*/
if(res == -1)
return;
}
return ;
}
Edit :
trying this
printf("%s -- ", tab[line].capitale);
printf("%s --", tab[line].pays);
printf("%s --\n", tab[line].commentaire);
gives me as result
-- --abi -- Emirats arabes unis
I expect to get
Abu Dhabi -- Emirats arabes unis --
Am I missing something?
Does printf have side effects?
Well, it prints to the screen. That's a side effect. Other than that: no.
is printf changing its parameters
No
I get wrong resutts [...] what is going on?
If by wrong results you mean that the output does not appear when it should, this is probably just a line buffering issue (your second version does not print newline which may cause the output to not be flushed).
It's highly unlikely that printf is your problem. What is far, far more likely is that you're corrupting memory and your strange results from printf are just a symptom.
There are several places I see in your code which might result in reading or writing past the end of an array. It's hard to say which of them might be causing you problems without seeing your input, but here are a few that I noticed:
get_lines_count won't count the last line if it doesn't end in a newline, but your other methods will process that line
advance will skip over a newline if it is preceded by spaces, which will cause your column-based processing to get off, and could result in some of your strings being uninitialized
get_word doesn't do any bounds checks on buffer
There may be others, those were just the ones that popped out at me.
I tested your code, adding the missing parts (MAX_LINE constant, main function and a sample datafile with three columns separated by 2+ whitespace), and the code works as expected.
Perhaps the code you posted is still not complete (fill_table() looks for a -999 magic number from get_word(), but get_word() never returns that), your main function is missing, so we don't know if you are properly allocating memory, etc.
Unrelated but important: it is not recommended (and also not portable) to do relative movements with fseek in text files. You probably want to use ungetc instead in this case. If you really want to move the file pointer while reading a text stream, you should use fgetpos and fsetpos.
Your approach for getting help is very wrong. You assumed that printf had side effects without even understanding your code. The problem is clearly not in printf, but you held information unnecessarily. Your code is not complete. You should create a reduced testcase that compiles and displays your problem clearly, and include it in full in your question. Don't blame random library functions if you don't understand what is really wrong with your program. The problem can be anywhere.
From your comments, i am assuming if you use these printf statements,
printf("%s\n", tableau[i].capitale);
printf("%s", tableau[i].pays);
printf("%s\n", tableau[i].commentaire);
then everything works fine...
So try replacing your single printf statement with this. (Line no. 173 in http://codepad.org/79aLzj2H)
printf("%s\n %s %s /n", tableau[i].capitale, tableau[i].pays, tableau[i].commentaire);