I'm not sure why this is throwing and exception - c

`
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main(void)
{
int charCounter = 0;
int intCounter = 0;
int otherCounter = 0;
int ch;
FILE* fp;
fp = fopen("infile.txt", "r");
while ((ch = getc(fp)) != EOF) {
if (isalpha(ch)) {
charCounter += 1;
}
else if (isdigit(ch))
{
intCounter += 1;
}
else
{
otherCounter += 1;
}
}
printf("There were %d char values \n there were %d int values \n there were %d other values ", charCounter, intCounter, otherCounter);
close(fp);
}
`
My code throws an exception after the while statement, and I'm not sure why
I'm new to C so im not sure where to start on this

Not sure what "throwing an exception" means in C. Here are the changes I made:
Added missing include files.
Add error check for fopen().
Used fclose() instead of the incorrect close(). Your compiler should have complained.
Added a newline to printf().
#define _CRT_SECURE_NO_WARNINGS
#include <ctype.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>
int main(void) {
FILE* fp = fopen("infile.txt", "r");
if(!fp) {
printf("%s\n", strerror(errno));
return 1;
}
int charCounter = 0;
int intCounter = 0;
int otherCounter = 0;
int ch;
while ((ch = getc(fp)) != EOF) {
if (isalpha(ch)) {
charCounter += 1;
} else if (isdigit(ch)) {
intCounter += 1;
} else {
otherCounter += 1;
}
}
printf("There were %d char values \n there were %d int values \n there were %d other values\n",
charCounter, intCounter, otherCounter);
fclose(fp);
}
and here is the output with a copy of the above program as "infile.txt":
There were 375 char values
there were 7 int values
there were 232 other values

Related

How can I verify if a file only contains numbers in 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

fscanf not reading from a file containing asterisk characters

I tried to read a file containing an empty box of '*', the error message doesn't get printed, so the file is opened, but the scan doesn't work. I tried to print the count variable, and the value of count is 0. I don't really know where the fault is. Please help... Thanks
the file content that I want to read
int openmap(int file_no){
char filename[32];
char mapp[100][100];
int number;
int count;
int x[100];
int nomor = 1;
for(int i = 1; i <= file_no; i++){
sprintf(filename, "map%d.txt", i);
FILE *test = fopen(filename,"r");
if(test)
{
printf("%2d. Map %d\n", nomor, i);
x[nomor-1] = i;
nomor++;
fclose(test);
}else if(!test && i > file_no){
printf("No map available!");
return 1;
}
}
do{
printf("[0 to cancel] [1 - %d]>> ", nomor-1);
scanf("%d", &number);
}while(number < 0 || number > file_no);
if(number > 0){
sprintf(filename,"map%d.txt", x[number-1]);
printf("%s", filename);
FILE *open = fopen(filename, "r");
if(!open){
printf("error");
}
while(!feof){
fscanf(open, "%[^\n]\n", mapp[count]);
count++;
}
fclose(open);
for(int i = 0; i < count ; i++){
printf("%s\n", mapp[i]);
}
}
}
I created a small test program:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void main () {
char mapp[100][100];
int i, count = 0;
char filename[32];
sprintf(filename, "test.txt");
FILE *open = fopen(filename, "r");
if(!open){
printf("error");
}
while(!feof(open)){
fscanf(open, "%[^\n]\n", mapp[count]);
count++;
}
fclose(open);
for(i = 0; i < count ; i++){
printf("%s\n", mapp[i]);
}
}
as far as i can see the only issue you have regarding the relevant section is your while loop condition, you should use: while(!feof(open)) - i tested my solution and it works so it seems that this is the only issue in your solution

Reading the result of a contest from a file and sort the name alphabetically with related score

i have to read from a file which contains names and scores the results of a contest but the function fscanf is not working properly.. Does it have to do with newlines or something?
I'll leave below the code and the screenshots of the issue i'm having.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct contest
{
char name[25];
int score;
}Contest;
int main(int argc, const char * argv[]) {
Contest players[100];
FILE *fp;
fp = fopen("contest.txt", "r");
if(fp == NULL)
{
fprintf(stderr, "Error: failed to open the file\n");
exit(EXIT_FAILURE);
}
int cnt = 0;
while(fscanf(fp, "%s %d", players[cnt].name, &players[cnt].score) != EOF)
{
++cnt;
}
char temp[25];
for(int t = 0; t < cnt; ++t)
{
for(int u = 0; u < cnt; ++u)
{
if(strcasecmp(players[t].name, players[u].name) > 0)
{
strcpy(temp, players[t].name);
strcpy(players[t].name, players[u].name);
strcpy(players[u].name, temp);
}
}
}
for(int t = 0; t < cnt; ++t)
{
fprintf(stdout, "Name : %s Score : %d\n", players[t].name, players[t].score);
}
fclose(fp);
return 0;
}
Input:
Randal  34
Leonel  67
Vaughn  100
Missy  68
Cristopher  92
Dagmar  102
Blondell  88
Milly  83
Darrel  12
Josh  71
Output:
You've just made two little mistakes: (1) forgot to also swap the scores and (2) did the wrong comparison in the strcasecmp. For the rest, it's all working fine here.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
typedef struct contest
{
char name[32];
int score;
} Contest;
int main()
{
Contest players[100];
FILE *fp = fopen("contest.txt", "r");
assert(fp);
int cnt = 0;
while(fscanf(fp, "%s %d", players[cnt].name, &players[cnt].score) != EOF)
++cnt;
for(int i = 0; i < cnt; ++i)
{
for(int j = 0; j < cnt; ++j)
{
if(strcasecmp(players[i].name, players[j].name) < 0)
{
int tempScore = players[i].score;
players[i].score = players[j].score;
players[j].score = tempScore;
char tempName[32];
strcpy(tempName, players[i].name);
strcpy(players[i].name, players[j].name);
strcpy(players[j].name, tempName);
}
}
}
for(int i = 0; i < cnt; ++i)
fprintf(stdout, "Name : %s Score : %d\n", players[i].name, players[i].score);
fclose(fp);
return 0;
}

Storing numbers as (x, y) cordinates from a file at a specific point

I have an Instance File from which I need to store the NUM_PT and all the respective co-ordinates in the form of a 2D array system (personal choice so I can access them easily). I am able to retrieve the NUM_PT but I am stuck at reading the successive cordinates into my array.
HERE IS WHAT I HAVE DONE
/* Assignment 2 */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <ctype.h>
#define MAXS 256
int main(int argc, char *argv[])
{
int num_pt;
int inputfile = 0, outputfile = 0, i;
for (i = 1; i < argc; i++)
{
if (strcmp (argv[i], "-i") == 0)
inputfile = i+1;
if (strcmp (argv[i], "-o") == 0)
outputfile = i+1;
}
if (inputfile == 0)
{
/* invalid command line options */
printf("\nIncorrect command-line...\n");
printf("> %s [-i inputfile [-o outputfile]]\n\n", argv[0]);
exit(0);
}
FILE *fp;
fp = fopen(argv[inputfile], "r");
int count = 0;
if (fp == 0)
{
printf("\nCould not find %s\n", argv[inputfile]);
exit(0);
}
char line[MAXS];
while (fgets(line, sizeof line, fp) != NULL)
{
if (count == 4)
{
fscanf(fp, "%d", &num_pt);
break;
}
else
count++;
}
int arr[num_pt][1];
while (fgets(line, sizeof line, fp) != NULL)
{
if (count == 5)
{
int k, j, cord;
for (k = 0; k < num_pt; k++)
{
for (j = 0; j < num_pt; j++)
{
while (fscanf(fp, "%d%d", &cord) > 0)
{
arr[k][j] = cord;
j++;
}
}
}
}
}
fclose(fp)
return 0;
}
After retrieving NUM_PT i tried reinitializing the count to 5 because the cordinates start from **LINE 6* in the file.
ERROR FROM COMPILER
Language: c99 ; Compiler: gcc
sample for "Storing numbers as (x, y) cordinates from a file" (It is better not to fix the reading position)
#include <stdio.h>
typedef struct point {
int x, y;
} Point;
int readPoint(FILE *fp, Point *p);
int readInt(FILE *fp, int *n);
int main(void){
FILE *fp = fopen("instance10_001.txt", "r");
Point p;
int MAX_X, MAX_Y;
readPoint(fp, &p);
MAX_X = p.x;
MAX_Y = p.y;
printf("MAX_X:%d, MAX_Y:%d\n", MAX_X, MAX_Y);
int NUM_PT;
readInt(fp, &NUM_PT);
printf("NUM_PT:%d\n", NUM_PT);
Point arr[NUM_PT];
for(int i = 0; i < NUM_PT; ++i){
readPoint(fp, &arr[i]);
printf("Point(%d, %d)\n", arr[i].x, arr[i].y);
}
fclose(fp);
}
int readLine(FILE *fp, char *buff, int buff_size){
while(fgets(buff, buff_size, fp)){
if(*buff == '#' || *buff == '\n')
continue;
return 1;
}
return 0;
}
#define LINE_MAX 128
int readPoint(FILE *fp, Point *p){
char buff[LINE_MAX];
if(readLine(fp, buff, sizeof buff)){
return 2 == sscanf(buff, "%d %d", &p->x, &p->y);
}
return 0;
}
int readInt(FILE *fp, int *n){
char buff[LINE_MAX];
if(readLine(fp, buff, sizeof buff)){
return 1 == sscanf(buff, "%d", n);
}
return 0;
}

fprintf saves wrong data to file

I have an input file a.txt:
1 abc 3
2 efgh 4.5
3 text 3
4 xyz 2
So basically, it has 3 columns, first one is int, second is text, and third is double. I need to read this file by rows (which actually works, I guess), but have some problems with writing only second and third column to another (b.txt) file. fprinft saves something like this:
0.000000
0.000000
0.000000
0.000000
xvæ$ 0.000000
instead of
abc 3
efgh 4.5
text 3
xyz 2
I simply need to save only the second and the third column from a.txt file to b.txt file. Here's my code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct mypair
{
char string[1024];
double number;
} mypair;
void zero_string(char *string, int n)
{
int i;
for(i=0; i<n; i++)
string[i] = '\0';
}
int row(FILE* f, struct mypair *p)
{
int num;
if(!feof(f))
{
if(fscanf(f,"%d %s %lf", &num, p->string, &p->number) == 3)
{
return 0;
}
}
else
{
return 1;
}
}
int main(int argc, char **argv)
{
int n = 5, status = 0, i = 0, j;
struct mypair array[5];
char file_in_name[255];
char file_out_name[255];
FILE *fin;
FILE *fout;
zero_string(file_in_name, 255);
zero_string(file_out_name, 255);
printf("Data file:\n> ");
scanf("%s", file_in_name);
printf("Out file:\n> ");
scanf("%s", file_out_name);
fin = fopen(file_in_name, "r");
fout = fopen(file_out_name, "w");
if( fin == NULL )
{
exit(-1);
}
if( fout == NULL )
{
exit(-1);
}
while(status != 1)
{
status = row(fin, &array[i]);
i ++;
fprintf(fout, "%s %lf\n", array[i].string, array[i].number);
if(i >= n)
break;
}
fclose(fin);
fclose(fout);
for(j=0; j<i; j++)
printf("%s %lf\n", array[i].string, array[i].number);
return 0;
}
I modified the code, now it works, thanks!
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct mypair
{
char string[1024];
double number;
} mypair;
void zero_string(char *string, int n)
{
int i;
for(i=0; i<n; i++)
string[i] = '\0';
}
int row(FILE* f, struct mypair *p)
{
int num;
if(!feof(f))
{
if(fscanf(f,"%d %s %lf", &num, p->string, &p->number) == 3)
{
return 0;
}
}
else
{
return 1;
}
}
int main(int argc, char **argv)
{
int n = 5, status = 0, i = 0, j;
struct mypair array[5];
char file_in_name[255];
char file_out_name[255];
FILE *fin;
FILE *fout;
zero_string(file_in_name, 255);
zero_string(file_out_name, 255);
printf("Data file:\n> ");
scanf("%s", file_in_name);
printf("Out file:\n> ");
scanf("%s", file_out_name);
fin = fopen(file_in_name, "r");
fout = fopen(file_out_name, "w");
if( fin == NULL )
{
exit(-1);
}
if( fout == NULL )
{
exit(-1);
}
printf("\n");
while(status != 1)
{
status = row(fin, &array[i]);
if(i >= n)
break;
else
{
if(status != -1)
fprintf(fout, "%s %lf\n", array[i].string, array[i].number);
}
i ++;
}
fclose(fin);
fclose(fout);
for(j=0; j<i; j++)
printf("%s %lf\n", array[j].string, array[j].number);
return 0;
}
In your bottom loop, you want to index your array by j, not i.

Resources