How do you run a file-reading program on itself in C? - c

I have only Java experience, and I'm starting to learn C through the K&R C book, second addition. In the first chapter, one of their examples is this program which simply counts the white space, characters, and digits:
#include <stdio.h>
main()
{
int c, i, nwhite, nother;
int ndigit[10];
nwhite = nother = 0;
for(i = 0; i < 10; i++){
ndigit[i] = 0;
}
while((c = getchar()) != EOF){
if(c >= '0' && c <= '9'){
++ndigit[c-'0'];
}
else if (c == ' ' || c == '\n' || c == '\t'){
++nwhite;
}
else{
++nother;
}
}
printf("digits =");
for(i = 0; i <10; ++i){
printf(" %d", ndigit[i]);
}
printf(", white space = %d, other = %d\n", nwhite, nother);
}
Next, in the book they say "the output of this program run on itself is " followed by its output. However, I've compiled the program in the terminal and just cannot figure out how to run this program on itself in C. In java, I would have passed the file name to String args[0] and read it from there, but this program doesn't have any similar mechanism, and doesn't seem to have an args array to pass to. Even if it did, the code itself doesn't seem to read from any particular file (for example, in java you could specifically set up a scanner to read args[0], and then call scanner.next() etcetc, but in this program, it just calls getchar() on seemingly nothing). Can anyone help me clear this up so I can run the program before continuing? Sorry if this is something super simple, like I said my experience in C is nonexistent. Thank you!
Also my formatting on this website is trash I apologize

I assume they intend to run this program like so:
./example < example.c
You are correct about the fact that the program does not open a file and it does not use arguments. The getchar() function operates on stdin.
The program does not make much sense if you use it on the compiled file, so that is why I assumed it is supposed to be run with the source file. I see how the instructions are confusing.

Related

how does this C code with input through < work? (K&R)

$ ./main < input
If I were to check for new lines in python, I would open the file and then analyze the lines, but this almost seems like magic.
int main(){
int c, nl;
nl = 0;
while ((c = getchar()) != EOF)
if (c == '\n')
nl++;
printf("%d\n", nl);
return 0;
}
How does it know to accept any input file without being stated within the code?
The < symbol in the shell is an input redirection. It states that the contents of the given file input in this case, will be read as stdin.
So any function such as getchar that reads from stdin will actually be reading from the file input in this case.
A similar program in Python would also use functions that read from stdin instead of from a file.

K&R different outputs from basically the same thing

I am currently working through K&R for C. In section 1.5, we basically create a program for word count. The code is as follows,
#include <stdio.h>
#define IN 1
#define OUT 0
int main()
{
int c;
long int nl, nc, nw;
int state;
nl = nw = nc = 0;
state = OUT;
while((c = getchar())!= EOF){
++nc;
if (c == '\n'){
++nl;
}
if (c == ' '||c == '\n'|| c == '\t'){
state = OUT;
} else if (state == OUT){
state = IN;
++nw;
}
}
printf("\n%ld %ld %ld\n", nl, nc, nw);
}
When I compile this program with gcc and open the executable and type something such as
Hello
World
I get output
1 11 2
Which makes sense as we have 1 '\n' newline characters, 11 characters (including newline), and 2 word. What is interesting is when I do
vim hello.txt
and type
Hello
World
and then issue the command
cat hello.txt|./a.out
I get the following output
2 12 2
Why are the outputs from this different from before because all I am doing is streaming the file into the executable so I do not understand what is different. Please do explain.
Thank You.
Not your program's feature, but Vim's. See: What does the noeol indicator at the bottom of a vim edit session mean?
Vim automatically appends a newline at the end of file if there isn't when saving.
Type
:set noeol
in Vim and save the file again, then your program will output 11 as the second number.
P.S. It's redundant to use cat something | program, just program < something is enough.
After you type the charactors into the file and save it, at the end of the file, a 0x0a is added to the end of the file automaticly

C printf() not returning values

I have a very simple C example program that does a crude count of characters words and spaces from input. The program compiles without error but when tested the program doesn't return any of the int variables via the print function. I am using VS2012 for coding and compiling. Stepping into the code shows that the values are being calculated correctly. Is there something wrong with my code or the compiler?
#include <stdio.h>
#define IN 1
#define OUT 0
/* count digits, white space, others */
main()
{
int c, nl, nw, nc, state;
state = OUT;
nl = nw = nc = 0;
while ((c = getchar()) != EOF){
++nc;
if(c == '\n'){
++nl;
}
if (c == ' ' || c == '\n' || c == '\t'){
state = OUT;
} else if (state == OUT){
state = IN;
++nw;
}
}
printf("%d %d %d\n", nl, nw, nc);
}
It works if you run it with stdin coming from a file a.exe < test.txt. It works if you run it with stdin coming from the console on Linux. It does not work if you run it with stdin coming from the console on Windows.
It must be some sort of Windows console oddity.
In order to see the actual output, start the debugger with Ctrl-F5. This will keep the console window open.
See this answer for more information.
Your loop is permanent. Meaning it doesn't end.. so it doesn't reach the call of printf.
EOF is indicator that clearly doesn't work like that here. You must break the loop on a specific key. Like enter for instance, which character decimal representation is 13 for carriage return. 10 for NL.

Using putchar and printf together in the same C Program?

I've written a small C program where I wanted to display the numeric ASCII value that corresponds to certain key presses.
My code follows. The problem is, after running the program, it accepts input, but doesn't do anything else. It doesn't even reach the first printf statement. I can't figure out what the issue is - is there a problem with mixing the getchar() function with the printf() function in the same program?
#include <stdio.h>
int main() {
const int numKeys = 256;
int keys[numKeys];
int i;
for (i = 0; i < numKeys; i++) {
keys[i] = 0;
}
printf("\n Start pressing some keys!\n\n");
int c;
while ((c = getchar()) != EOF) {
printf(" CAPTURED: %d\n", c);
keys[c]++;
}
printf("\n\n ** RESULTS ** \n\n");
for (i = 0; i < numKeys; i++) {
if (keys[i] != 0) {
printf(" Key with value %d was called %d times.", i, keys[i]);
}
}
}
I should clarify that I have a Windows XP Pro machine, with Cygwin installed. I use Cygwin for my development space, so I wonder if there is something different when running this type of program in that environment.
I found the problem. I think you want to use
while ((c = getchar()) != EOF && c != '\n')
Instead if you want to have it print the results after the person hits enter/return.
problem 1 : getting to printf(" CAPTURED: %d\n", c); without having to press the Enter key
solution : is by using getche() in while loop.
problem 2 : getting to 'printf("\n\n ** RESULTS ** \n\n");' or essentially breaking while loop?
solution : you cannot. you will never get EOF as long as you read from keyboard.
workaround : close stdin or use a escape character other than EOF.
EDIT : workaround2 :
->use getchar() itself. but to print those entered char u need to press Enter key. now on windows ctrl+z gives EOF but this should be the **FIRST** input on the line after you press Enter key. well this is not a good solution.
if you want a "Press key display times pressed scenario. there is just no simple way(AFAIK)"
I believe that the first printf statement gets executed, but due to buffering is not displayed on the screen immediately. Use fflush(stdout) to send the contents of the buffer to the screen. Ie:
printf("\n Start pressing some keys!\n\n");
fflush(stdout);

My c program to remove lines from a text file works on a small file, but has a stacksmash error with a large file

I am working on a program to filter a list of craigslist results; I want to find a relatively cheap room for rent. The finished program will remove lines that have a price over $600, and create a new file, but for now I am removing every line with a $ character, and printing to the terminal.
The program works fine when run on its own source, but when I run it on an html page of craigslist results saved from Firefox, it prints until the closing html bracket and throws a stack smashing detected warning and a backtrace. I am learning C from K&R so if this code looks antiquated that's why.
# include <stdio.h>
# define MAXLINE 300
main()
{
char line[MAXLINE];
int c;//current character
int p = 0;//position in the line
int flag = 0;//there is a dollar sign
while ((c = getchar()) != EOF){
line[p++] = c;
if (c == '$'){
flag = 1;
}
if (c == '\n'){
if(flag == 0){//there was no $, print the line
int i;
for(i=0;i<p;i++){
putchar(line[i]);
line[i] = '\0';
}
}
p = 0;
flag = 0;
}
}
}
I imagine the problem is just that the HTML contains at least one line that is more than MAXLINE characters long. You don't check anywhere whether you're about to exceed the size of the array; if you do, you would indeed smash the stack. Your while loop could check whether p was less than MAXLINE, print a message if not, and stop. You couldn't do anything else without fairly significant changes to your program.

Resources