So basically I am writing a C program that reads a stream of bytes from standard input and treats the bytes as unsigned integers in the range 0 to 255 inclusive. The program counts how often each value in the range 0 to 255 occurs. It also accepts a nonnegative integer as a command line argument. This command line argument gives the number of lines, n, of output the program should produce. Thus, if n is 16, the program should print 16 lines of output showing how often the byte values in the range 0 to 15 inclusive occurred.
Each line should begin with the integer value followed by the count, eg
0 occurred 1014 times
1 occurred 1201 times
and so on.
I try to read a char each time from stdin and check if it's "\\n". However the condition (token != "\\n") never returns False and the loop is never broken.
Here is my code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, const char* argv[]) {
char token;
int n;
if (argc != 2) {
printf("Error!\n");
exit(0);
}
n = atoi(argv[1]);
int i;
int freq[n];
for(i = 0; i<n; i++) {
freq[i] = 0;
}
int value;
printf(">");
token = fgetc(stdin);
while (token != "\n") {
printf("here!");
value = token;
if (value < n) {
freq[value] ++;
}
token = fgetc(stdin);
}
printf("there");
for(i = 0; i<n; i++) {
printf("%d occured %d times\n",i, freq[i]);
}
return 1;
}
I try to read a char each time from stdin and check if it's "\\n". However the condition (token != "\\n") never returns False and the loop is never broken.
That's because:
while (token != "\n") {
is an error. That should be:
while (token != '\n') {
Your compiler should warn about that error. This is what I get when I compile the program using gcc -Wall
:
soc.c: In function ‘main’: soc.c:25:18: warning: comparison between pointer and integer [enabled by default] while (token != "\n") { ^ soc.c:25:18: warning: comparison with string literal results in unspecified behavior [-Waddress]
To be more safe, use:
while (token != '\n' && token != EOF ) {
Also, you should change the type used for token
from char
to int
. Return type of fgetc()
is int
. If your platform uses unsigned
type for char
, you will run into problems with capturing EOF
, which is often -1
.
you may use getchar();
-
int c;
while((c=getchar())!=EOF){
}
the following is the posted code, with comments..
// <-- strongly suggest reading the manual for the system functions you use
// so the error on the returned value from fgetc() would not have happened
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, const char* argv[])
{
char token; // <-- fgetc and getchar return integer, not character
int n;
if (argc != 2)
{
printf("Error!\n"); // <-- this should be a 'usage' statement
exit(0); // <-- this exit is due to an error, returned value should be a non-zero value to indicate an error occurred
}
// implied else, right number of parameters.
n = atoi(argv[1]); // <-- check that 'n' is not zero and not negative and <= 255
// <-- output an error message and exit of value is not good
// implied else, parameter valid
int i;
int freq[n];
for(i = 0; i<n; i++)
{
freq[i] = 0;
}
int value;
printf(">");
// <-- suggest modification to while(), so fgetc() embedded in while statement
token = fgetc(stdin);
while (token != "\n") { // <-- this is a comparison between pointer and integer, compiler warning
// <-- comparions with string literal results in unspecified behavior
printf("here!");
// <-- token, after correcting declartion to int eliminates the need for 'value'
value = token;
if (value < n) {
freq[value] ++;
}
token = fgetc(stdin);
}
printf("there");
for(i = 0; i<n; i++) {
printf("%d occured %d times\n",i, freq[i]);
}
return 1; // <-- this is the 'good' exit, so should return 0
}
Generally, what you're trying to do is accomplished as doing the following:
int ch;
while((ch = getchar()) != '\n' && ch != EOF)
{
// ...
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.