How can I verify if a file only contains numbers in C? - c

I'm a beginner in learning C. If I have a file with the given format:
12 20 40 60 80
04 10 34 30 20
How can I verify with a function that it's integers only.
I'm working on an assignment that requires me to do this. That is why I can't include my main but I am passing a file into my function.
bool check(FILE *fp) {
int numArray[26];
int i = 0;
int num;
while(fscanf(fp, "%d", &num)) {
if (isdigit(num) == 0) {
fprintf(stderr, "Not correct format ");
return false;
} else
{
numArray[i] = num;
i++;
}
}
}
If I give it the incorrect format such as
12x 10 15 13 10
Nothing happens. I was wondering if anyone can point me in the right direction?

fscanf will return the number of successfully recognized patterns from the format in the input; if it sees something that does not match the next format pattern (such as a letter for a %d pattern) it will reject it and return a smaller number. So in your case, you can just look for fscanf returning 0:
bool check(FILE *fp) {
int numArray[26];
int i = 0;
int num;
int matched;
while ((matched = fscanf(fp, "%d", &num)) != EOF) {
if (matched == 0) {
fprintf(stderr, "Not correct format\n");
return false;
} else if (i >= 26) {
fprintf(stderr, "Too many numbers\n");
return false;
} else
{
numArray[i] = num;
i++;
}
}
return true;
}

int is_number(char *str)
{
int i = 0;
while (str[i] != '\0')
{
if (str[i] < '0' || str[i] > '9')
return 0;
i++;
}
return 1;
}
maybe this. so you are looking if variable only has numbers?

ok maybe this works better
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
int main()
{
FILE *fp;
char c;
char s[100];
int i = 0;
fp = fopen("test.txt", "r");
if(fp == NULL)
{
printf("Error opening file");
exit(1);
}
while((c = fgetc(fp)) != EOF)
{
if(isdigit(c) == 0)
{
printf("Not only integers\n");
break;
}
}
if(c == EOF)
printf("Only integers\n");
fclose(fp);
return 0;
}
but yeah its pretty much same thing

Related

strstr not performing upto expectations

i cant seem to find whats wrong with my logic that the strstr not performing upto my expectations
its a question to find prime number in a binary string, and i'm finding 10 or 11 in that string and the outcome is not what i've expected.
sorry if i've done a terrible silly mistake, i'm a noob.
#include <stdio.h>
#include <string.h>
int main(void)
{
int t;
scanf("%d", &t);
while (t--)
{
char str[100000];
scanf("%s", str);
char ten[] = "10";
char eleven[] = "11";
int flag = 0;
if (strstr(str, ten) == NULL)
{
flag = 1;
}
else if (strstr(str,eleven) == NULL)
{
flag = 1;
}
if (flag == 1)
{
printf("NO\n");
}
else if (flag == 0)
{
printf("YES\n");
}
}
return 0;
}
input providing is
3 //test cases
1 //strings
111
101101
output getting
NO
NO
YES
output expecting
NO
YES
YES
You say you want your code to output "YES" for "111". For that to happen, you must leave flag at zero. But you set flag to one if the string contains no "10" and "111" contains no "10".
this code is working fine. i've made some adjustments, thanks to you guys.
#include <stdio.h>
#include <string.h>
int main(void)
{
int t;
scanf("%d", &t);
while (t--)
{
char str[100000];
scanf("%s", str);
char ten[] = "10";
char eleven[] = "11";
int flag = 1;
char *one = strstr(str, ten);
char *two = strstr(str, eleven);
if ((one == NULL) && (two == NULL))
{
flag = 0;
}
else
{
flag = 1;
}
if (flag == 0)
{
printf("NO\n");
}
else if (flag == 1)
{
printf("YES\n");
}
}
return 0;
}
The problem is with the if Statement. If '10' is not found in the first two characters, it would terminate there. Not checking for 11 also.
#include <stdio.h>
#include <string.h>
int main(void)
{
int t;
scanf(" %d", &t);
while (t--)
{
char str[100000];
scanf(" %s", str);
char ten[] = "10";
char eleven[] = "11";
int flag = 0;
if (strstr(str, ten) == NULL && strstr(str,eleven) == NULL)
{
flag = 1;
}
if (flag == 1)
printf("NO\n");
else
printf("YES\n");
}
return 0;
}

*pointer_variable != '\0' is not working for the check of unsuccessful conversion in strtol() function

The program was not working for input 5r i.e in input when first character is number and remaining next character is any alphabet or negative number. For example when I am giving input as 5r in the output I am getting factorial of 5.
So I tried putting check for strtol unsuccessful conversion :-
if (p == buf || *p != '\0'){ printf("\nInvalid input: not a number\n");}
but I am getting output as Invalid input: not a number for all the input.
I found many similar questions in Stack Overflow. However, they don't resolve my issue. I am not understanding what is wrong with this simple check? How can I successfully detect errors from strtol?
#include <stdio.h>
#include <limits.h>
#include <stdlib.h>
#include <errno.h>
int display();
void fact_fun(int num_fact);
int main()
{
int num;
while ((num = display()) >= 0)
{
fact_fun(num);
}
return 0;
}
int display()
{
char buf[256];
char *p;
long value;
for (;;)
{
printf("\nEnter number to find factorial or press ENTER KEY to exit: ");
if (fgets(buf, sizeof buf, stdin) == NULL || *buf == '\n')
return -1;
errno = 0;
value = strtol(buf, &p, 0);
if (p == buf || *p != '\0')
{
printf("\nInvalid input: not a number\n");
}
else
{
if (value < 0)
{
printf("\nInvalid input: negative values not allowed\n");
}
else if (errno != 0 || value > INT_MAX)
{
printf("\nInvalid input: value too large for type int\n");
}
else
{
return (int)value;
}
}
}
}
void fact_fun(int num_fact)
{
int fact = 1;
for (int i = 1; i <= num_fact; i++)
{
if (fact > INT_MAX / i)
{
printf("\nInvalid input: arithmetic overflow\n");
return;
}
fact = fact * i;
}
printf("\nFactorial of %d is %d\n", num_fact, fact);
}
The string you get from fgets contains '\n' as last char because you hit enter, so replace it with '\0'. That is a common error we C coders sometimes make.
Edit:
So I have tested it myself, and you're right, the reason is that strtoI does not mess with line terminator, so now it works fine with the following check:
*p != '\n'
The full working code is this:
#include <stdio.h>
#include <limits.h>
#include <stdlib.h>
#include <errno.h>
int display();
void fact_fun(int num_fact);
int main()
{
int num;
while ((num = display()) >= 0)
{
fact_fun(num);
}
return 0;
}
int display()
{
char buf[256];
char *p;
long value;
for (;;)
{
printf("\nEnter number to find factorial or press ENTER KEY to exit: ");
if (fgets(buf, sizeof buf, stdin) == NULL || *buf == '\n')
return -1;
errno = 0;
value = strtol(buf, &p, 0);
if (p == buf || *p != '\n')
{
printf("\nInvalid input: not a number\n");
}
else
{
if (value < 0)
{
printf("\nInvalid input: negative values not allowed\n");
}
else if (errno != 0 || value > INT_MAX)
{
printf("\nInvalid input: value too large for type int\n");
}
else
{
return (int)value;
}
}
}
}
void fact_fun(int num_fact)
{
int fact = 1;
for (int i = 1; i <= num_fact; i++)
{
if (fact > INT_MAX / i)
{
printf("\nInvalid input: arithmetic overflow\n");
return;
}
fact = fact * i;
}
printf("\nFactorial of %d is %d\n", num_fact, fact);
}

How to ignore the ctrl+z, when checking the most common letter in a file (not case sensitive)

The function needs to find the most common character in a file and also get the data from the user. I used ctrl+z to terminate.
The problem is when I enter big character like: A + ctrl+Z, then it counts the Z as the most common one.
(If there is the same amount of character, it will return the biggest alphabetically. Empty file will return '\0').
char commonestLetter(){
char ch;
int count[26] = {0}, max = 0, index, i;
FILE* f = fopen("input.txt","w");
if (f == NULL){
printf("Failed to open the file \n");
return;
}
printf("Please enter the characters one by one, followed by enter\n");
printf("Ctrl + z and enter to finish\n");
while((ch = getchar()) != EOF){
fprintf(f,"%c",ch);
_flushall();
if (isalpha(ch))
count[ch - 'a']++;
}
fseek(f, 0, SEEK_END);
if (ftell(f) == 0){
ch = '\0';
return ch;
}
for (i = 0; i < 26; i++){
if (count[i] >= max){
max = count[i];
index = i;
}
}
fclose(f);
return index + 'A';
}
int main(){
char ch;
ch = commonestLetter();
if(ch)
printf("The commonest letter is %c", ch);
else
printf("No letters in the file");
printf("\n");
system("pause");
return 0;
}
You declared that the function should find the most common letter IN A FILE, but you read letters from stdin.
To get the most common letter ignoring case, you have to use letter-elevating function like tolower().
Try this:
#include <stdio.h>
#include <ctype.h>
char commonestLetter(char *file_name)
{
char ch, max_char = '\0';
int count[26] = {0}, max_count = 0;
FILE *f = fopen(file_name, "r");
if (f == NULL) {
printf("Failed to open the file %s\n", file_name);
return '\0';
}
while (fread(&ch, 1, 1, f) > 0) {
if (isalpha(ch) &&
(++count[tolower(ch) - 'a']) > max_count)
max_char = ch;
}
fclose(f);
return max_char;
}
int main(int argv, char *argc[])
{
char ch;
if (argv < 2) {
printf("Usage: %s filename\n", argc[0]);
exit();
}
ch = commonestLetter(argc[1]);
if(ch)
printf("The commonest letter in the file %s is '%c'\n",
argc[1], ch);
else
printf("No letters in the file %s\n", argc[1]);
return 0;
}

C: Occurrence of Letters in Text file

Program takes an input file through the command line and outputs the occurrence of each letter in the text file. Not sure where I went wrong.
int main(int argc, char *argv[]) {
char word[1000];
int a = 0;
int b = 0;
int d = 0;
int c = 0;
int e = 0;
int f = 0;
int g = 0;
int h = 0;
int i = 0;
int j = 0;
int k = 0;
int l = 0;
int m = 0;
int n = 0;
int o = 0;
int p = 0;
int q = 0;
int r = 0;
int s = 0;
int t = 0;
int u = 0;
int v = 0;
int w = 0;
int x = 0;
int y = 0;
int z = 0;
int other = 0;
int counter, lenght;
FILE *fp = fopen(argv[1], "r");
fgets(word, 999, fp);
lenght = 1000;
for(counter = 0; counter < lenght; counter++) {
word[counter] = tolower(word[counter]);
if (word[counter] == 'a') {
a++;
}
else if (word[counter] == 'b') {
b++;
}
else if (word[counter] == 'c') {
c++;
}
else if (word[counter] == 'd') {
d++;
}
else if (word[counter] == 'e') {
e++;
}
else if (word[counter] == 'f') {
f++;
}
else if (word[counter] == 'g') {
g++;
}
else if (word[counter] == 'h') {
h++;
}
else if (word[counter] == 'i') {
i++;
}
else if (word[counter] == 'j') {
j++;
}
else if (word[counter] == 'k') {
k++;
}
else if (word[counter] == 'l') {
l++;
}
else if (word[counter] == 'm') {
m++;
}
else if (word[counter] == 'n') {
n++;
}
else if (word[counter] == 'o') {
o++;
}
else if (word[counter] == 'p') {
p++;
}
else if (word[counter] == 'q') {
q++;
}
else if (word[counter] == 'r') {
r++;
}
else if (word[counter] == 's') {
s++;
}
else if (word[counter] == 't') {
t++;
}
else if (word[counter] == 'u') {
u++;
}
else if (word[counter] == 'v') {
v++;
}
else if (word[counter] == 'w') {
w++;
}
else if (word[counter] == 'x') {
x++;
}
else if (word[counter] == 'y') {
y++;
}
else if (word[counter] == 'z') {
z++;
}
else {
other++;
}
}
printf("\nCharacter frequency in %s", argv[1]);
printf("\nCharacter Count");
printf("\na \t\t %d", a);
printf("\nb \t\t %d", b);
printf("\nc \t\t %d", c);
printf("\nd \t\t %d", d);
printf("\ne \t\t %d", e);
printf("\nf \t\t %d", f);
printf("\ng \t\t %d", g);
printf("\nh \t\t %d", h);
printf("\ni \t\t %d", i);
printf("\nj \t\t %d", j);
printf("\nk \t\t %d", k);
printf("\nl \t\t %d", l);
printf("\nm \t\t %d", m);
printf("\nn \t\t %d", n);
printf("\no \t\t %d", o);
printf("\np \t\t %d", p);
printf("\nq \t\t %d", q);
printf("\nr \t\t %d", r);
printf("\ns \t\t %d", s);
printf("\nt \t\t %d", t);
printf("\nu \t\t %d", u);
printf("\nv \t\t %d", v);
printf("\nw \t\t %d", w);
printf("\nx \t\t %d", x);
printf("\ny \t\t %d", y);
printf("\nz \t\t %d", z);
fclose(fp);
return 0;
}
Should output in two columns one being the letter and the next being the number of times that letter occurs
There are problems in your code:
you do not include <stdio.h> nor <ctype.h>
you only read one line and you do not even check if that succeeds. You should write a loop like while (fgets(word, sizeof word, fp)) {
you check all characters in the word array: you should stop at the end of the line: lenght = strlen(word);
tolower() should not be given a char argument, because on platforms where char is signed, negative values invoke undefined behavior. You can cast the argument as (unsigned char) to avoid this: word[counter] = tolower((unsigned char)word[counter]);
More room for improvement:
lenght is misspelt, it should be length.
you should use an array of counters to avoid all these tests and all these explicit printf statements.
check the argument count and fopen() success
no need to read line by line, handle one byte at a time read with getc(). However, reading one large chunk at a time can be faster because it uses fewer tests and locks.
the printf statements should output the newline at the end rather than at the beginning.
Here is a corrected and simplified version:
#include <ctype.h>
#include <limits.h>
#include <stdio.h>
int main(int argc, char *argv[]) {
int count[UCHAR_MAX + 1] = { 0 };
int other, total;
int c;
const char *s;
FILE *fp;
if (argc <= 1) {
fprintf(stderr, "missing input file\n");
return 1;
}
fp = fopen(argv[1], "r");
if (fp == NULL) {
fprintf(stderr, "cannot open input file %s\n", argv[1]);
return 1;
}
total = 0;
while ((c = getc(fp)) != EOF) {
count[tolower(c)] += 1;
total++;
}
printf("Character frequency in %s\n", argv[1]);
printf("Character Count\n");
other = total;
for (s = "abcdefghijklmnopqrstuvwxyz"; *s; s++) {
printf("%c:\t%9d\n", *s, count[(unsigned char)*s]);
other -= count[(unsigned char)*s];
}
printf("other:\t%9d\n", other);
fclose(fp);
return 0;
}
Reading the file by chunks instead of one byte at a time improves the speed dramatically with recent C libraries, because the support for multithreading has made the getc() macros inefficient. Using 64K buffers, the code below is fifty times faster (50X) for a 400MB file:
#include <ctype.h>
#include <limits.h>
#include <stdio.h>
#define BUFFER_SIZE 65536
int main(int argc, char *argv[]) {
unsigned char buffer[BUFFER_SIZE];
long count[UCHAR_MAX + 1] = { 0 };
long other;
size_t i, n;
const char *s;
FILE *fp;
if (argc <= 1) {
fprintf(stderr, "missing input file\n");
return 1;
}
fp = fopen(argv[1], "r");
if (fp == NULL) {
fprintf(stderr, "cannot open input file %s\n", argv[1]);
return 1;
}
while ((n = fread(buffer, 1, sizeof buffer, fp)) != 0) {
for (i = 0; i < n; i++) {
count[buffer[i]] += 1;
}
}
other = 0;
for (i = 0; i <= UCHAR_MAX; i++) {
if (isupper(i)) {
count[tolower(i)] += count[i];
} else {
if (!islower(i))
other += count[i];
}
}
printf("Character frequency in %s\n", argv[1]);
printf("Character Count\n");
for (s = "abcdefghijklmnopqrstuvwxyz"; *s; s++) {
printf("%c:\t%9ld\n", *s, count[(unsigned char)*s]);
}
printf("other:\t%9ld\n", other);
fclose(fp);
return 0;
}
Here's a quick implementation I wrote. It doesn't use fgets, but that is most definitely an option.
The flow of the program should be simple, but it is as follows:
Check for a proper argument count.
Declare the variables we'll need.
Declare the file pointer and attempt to open the file.
If the file doesn't open, we'll error out.
Read in every character from the file one at a time and store it into our variable c.
Using our ascii table, we'll alter the values to get them into the proper position in our array.
Print out all of our values.
Close the file.
#include <stdio.h>
int main(int argc, char **argv){
if (argc < 2){
printf("Not enough arguments!\n");
return -1;
}
int A[27] = {0}, c;
FILE *inFile = fopen(argv[1], "r");
if (inFile == NULL){
printf("The file \"%s\" could not be opened.\n", argv[1]);
return -2;
}
while((c = fgetc(inFile)) != EOF){
if ( c >= 'a' && c <= 'z' ){
/* C is a lowercase character */
c-='a';
A[c]++;
}
else if ( c >= 'A' && c <= 'Z' ){
/* C is an uppercase character */
c-='A';
A[c]++;
}
else if (c == '\n'){
/* we're not counting newlines */
continue;
}
else {
A[26]++;
}
}
/* Print out all the values except the "Other" count. */
for (c = 0; c < sizeof A / sizeof A[0] - 1; c++){
printf("%c: %d\n", c+'a', A[c]);
} printf("Other: %d\n", A[26]); //Print out "Other" count
/* Close our file */
fclose(inFile);
return 0;
}

C program to read a file and print just the numbers

I have a file containing strings as well as numbers. Eg. my file Store-1.txt contains "coffee 2mug -4".
I need a c program to store the numbers only (i.e 2 and -4) by reading a file and saving just the numbers into an array.
i am not able to figure out how exactly to do this. Any suggestions please.
code is
#include <stdio.h>
int main(void)
{
char c,ch;
int flag=0;
FILE *fptr=fopen("Store-1.txt","r");
if(fptr)
{
while((c=fgetc(fptr))!=EOF)
{
if(c=='-' || c== '+')
{
ch=c;
flag=1;
}
if(c>='0' && c<='9')
{
if(flag == 1)
{
printf("%c",ch); flag =0;
}
printf("%c",c);
}
}
}
else
printf("Error : file not found");
system("pause");
}
read a file using fgetc() and printf() it if
c>='0' && c<='9'
Here is the full working code :
#include <stdio.h>
int main()
{
char c,ch;
int flag=0;
FILE *fp=fopen("file.txt","r");
if(fp)
{
while((c=fgetc(fp))!=EOF)
{
if(c=='-' || c== '+')
{
ch=c;
flag=1;
continue;
}
if(c>='0' && c<='9')
{
if(flag == 1)
{
printf("%c",ch); flag =0;
}
printf("%c",c);
}
else
flag=0;
}
}
else
printf("Error : file not found");
fclose(fp);}
#include <ctype.h>
#include <stdio.h>
int main(void)
{
int ch, n, sign;
sign = 1;
ch = getchar();
while (ch != EOF) {
if (ch == '-') {
sign = -1;
ch = getchar();
} else if (isdigit(ch)) {
n = 0;
do {
n = n * 10 + ch - '0';
ch = getchar();
} while (isdigit(ch));
n *= sign;
/*store n*/
} else {
sign = 1;
ch = getchar();
}
}
return 0;
}

Resources