I need to write a program that opens a txt file and lists how many numbers are there (e.g. there are 25 numbers below) and then lists which number is the largest (max) and which is the smallest (min). The program then makes an average of these numbers.
So far, my program only write how many numbers I got there. When I try to make the formula to the maximum, I simply stop and can't move.
Can you help me? How do I do that by reading the rows and evaluating the largest number?
#include <stdio.h>
FILE *input;
int open()
{
if ((input = fopen("data.txt", "r")) == NULL)
{
printf("Error! opening file");
return 0;
}
}
int rows_reading ()
//Here i dont know what to do
{
input = fopen ("data.txt", "r");
}
void main ()
{
char c;
int linesCount = 0;
float max, min;
float a;
float n;
int count = 0;
input = fopen ("data.txt", "r");
while ((c = fgetc(input)) !=EOF)
{
if(c =='\n')
linesCount++;
} // this works
while ((c = getc(input)) !=EOF)
{
for (a = 0; a < count; a++){
if (a > max)
max = a;
}
} //this not work
printf("In file is %d numerical values. Max value is %d"linesCount, max);
return ;
} ```
Hints only since it's classwork and you'll become a better developer if you nut it out yourself :-)
The idea is to scan all the numbers and remember which was the largest and smallest. For the average, you also need to accumulate a sum of all those number along with the count.
For example, consider the following pseudo-code:
def getMinMaxAvg(inputFile):
set sum, count, smallest, largest all to zero
set value to inputFile.getNumber()
if none available, return error indication
while true
if count is zero or value is less than smallest:
set smallest to value
if count is zero or value is greater than largest:
set largest to value
add value to sum
add one to count
set value to inputFile.getNumber()
if none available, return (smallest, largest, sum / count)
That's basically the flow you need. The first important thing here is the inputFile.getNumber(), the thing that gets your numbers. Your use of fgetc will input single characters, you'll probably want to use fscanf with the "%d" specifier, so you can input integers.
Just make sure you check the return value to ensure it worked okay:
int myInt; FILE *fileHandle = fopen(...);
if (fscanf(fileHandle, "%d", &myInt) != 1)
// Did not scan properly, needs to be handled.
// Now, myInt contains your value.
You're reading your file character by character, which isn't a good way to read numbers. If the file contains the number "137" you will read '1', then '3', then '7'. It works for counting lines since you can just count the number of '\n' characters, which you're doing.
Does the file contain a list of numbers, one number per line? If so, you should use fgets to read the file one line at a time. Then you can use atoi to convert the string into an integer and look for the max, min, etc. One gotcha that you have to look out for us that fgets will store the \n in the string it returns, so you may need to remove it.
If your file contains numbers separated by spaces then you might consider fscanf, which may work too for lines...? Not really sure about that since it's been ages since I used fscanf.
Related
I was having trouble reading and storing the last set of values from a text file. For example, let's say that this is printed in a text file:
ID Grade
AA22 12
BB33 13
DD44 14
How do I read only the grades of the student and store it in an integer in order to carry out calculations?
#include <stdio.h>
#include <string.h>
#include <stdlb.h>
FILE *fp;
int counter;
int main () {
fp = fopen ("nameoffile.txt", "r");
int line[50];
while (fgets(line, 50, fp) != EOF) {
counter = counter + line;
}
printf("The total amount is %d", counter);
}
It was originally written, and the question asked was similar to the example given. I am really more concerned about the logic.
Here is some code to get you started. You can use this as a base on top of which to build the logic that suits you.
Many error checking must be done, but I left this to you to figure out what needs to be improved.
I suggest you to first analyze it and understand what exactly happens, because there were many fundamentals errors with your code.
int main(void)
{
FILE *fp;
fp = fopen("nameoffile.txt", "r");
char line[200];
char ids[20][20];
int grades[20];
int cnt;
cnt = 0;
while (fgets(line, sizeof(line), fp) != NULL)
{
if(cnt)
sscanf(line, "%s %d", ids[cnt - 1], &grades[cnt - 1]);
cnt++;
}
printf("ID GRADE\n");
for(int i = 0; i < cnt - 1; i++)
{
printf("%s %d\n", ids[i], grades[i]);
}
return 0;
}
It seems that you know how to code but having trouble breaking down the project. Breaking down the project becomes the logic. It's helpful to breakdown the project and then google each point you don't understand. Cause clearly your project is information overload to you. Just try it next time.
And sure this is a lot of stuff to do but using this method you'll save a lot of time in the long run. ✔︎
Breakdown
• Read file
• Identify the "Grade" column.
• Read only those values under the "Grade column".
• Make sure the value's characters are all isdigit()
• Convert the values to integers:atoi() then Add those values to an array for whatever use you want to make of them later. to carry out calculations as you said.
Research Breakdown
• Read file
=> C Read Text File ... Now you have access to each line
• Identify the "Grade" column
=> multiple spaces to only one => by doing this step, its now easy to identify what your Columns "ID Grade ... ..." are delimited by.
=> Find a substring of a string in C ... Now you know you're currently on the line of your HEADERS ... You'll use this headers to figure out what column your grades are under.
=> By using the strstr() example the great internet provided you with, you now have at your disposal the index number of the starting character of the word "Grade".
=> Lucky for you, you already made the column delimiter a single space, so now you loop over the string until you reach that index number.
=> But while doing so, you need to count the amount of spaces you encounter. Because when your loop reaches the index number, you would have the column number of your grades - "Grade", which is actually nothing but the number of spaces.
• Make sure the value's characters are all digits
isdigit()
=> loop to the column where your grades value lies... you can do this because you know the column number and the column delimiter.
=> when you reach that point in the string, start checking if each character after that isdigit(). by "each character after that" i mean, all characters until you reach a space.
=> if you encountered a character thats something other a digit then throw a little syntax error or something cooler than that. your program!
=> now that you know the grades value is all digits, you want to atoi() that bad boy. but how ? something like this... ... this example code is how to get that value out of the whole string. Now you need to take that value in atoi(value).
=> then you'll add the return value of atoi(value) to your values
Good luck
Let's say I'm reading in numbers from a text file. The text file consists of one-hundred fifty digit numbers (those are separate, there are 100 instances of 50 digit numbers).
I wanted to save each number as a row of a 2D array. To do this, I declared an array
char input[99][50] //50 columns to utilize the newlines in the text file
But it wouldn't read in the entire text file, even though, it seemed to me, it was the right size. It read in through the 99th number. For the 100th line, it printed a newline then a bunch of garbage symbols, etc. Please see the following:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
//Set up the use of the input text file
FILE * ifp;
ifp = fopen("input.txt", "r");
//Declare variables
char input[100][50]; //Array to hold the input numbers
int i, j; //Variables to work with loops
//Begin by reading in the input file as characters,
//otherwise fscanf will take each entire line as
//a single number
for (i = 0; i <= 99; i++)
{
printf("%d)", i);
for (j = 0; j <= 50; j++)
{
fscanf(ifp, "%c", &input[i][j]);
printf("%c", input[i][j]);
}
}
system("pause");
return 0;
}
This will print it correctly. The thing that seems weird to me, is that it doesn't actually need to use that extra row that solves the problem...fscanf still only functions for the same range as before (0-99).
So...why does the array need to be [100]x[50]? Why does [99]x[50] cause so many issues?
Also, I added a newline to the last line of the text file because if I didn't, instead of a newline it printed an apostrophe ' to the screen at the end of the last line. Is this the symbol for some sort of end of file character?
Thanks in advance!
By the way, if you're interested in compiling this and seeing it happen, here's the text file input.txt:
37107287533902102798797998220837590246510135740250
46376937677490009712648124896970078050417018260538
74324986199524741059474233309513058123726617309629
91942213363574161572522430563301811072406154908250
23067588207539346171171980310421047513778063246676
89261670696623633820136378418383684178734361726757
28112879812849979408065481931592621691275889832738
44274228917432520321923589422876796487670272189318
47451445736001306439091167216856844588711603153276
70386486105843025439939619828917593665686757934951
62176457141856560629502157223196586755079324193331
64906352462741904929101432445813822663347944758178
92575867718337217661963751590579239728245598838407
58203565325359399008402633568948830189458628227828
80181199384826282014278194139940567587151170094390
35398664372827112653829987240784473053190104293586
86515506006295864861532075273371959191420517255829
71693888707715466499115593487603532921714970056938
54370070576826684624621495650076471787294438377604
53282654108756828443191190634694037855217779295145
36123272525000296071075082563815656710885258350721
45876576172410976447339110607218265236877223636045
17423706905851860660448207621209813287860733969412
81142660418086830619328460811191061556940512689692
51934325451728388641918047049293215058642563049483
62467221648435076201727918039944693004732956340691
15732444386908125794514089057706229429197107928209
55037687525678773091862540744969844508330393682126
18336384825330154686196124348767681297534375946515
80386287592878490201521685554828717201219257766954
78182833757993103614740356856449095527097864797581
16726320100436897842553539920931837441497806860984
48403098129077791799088218795327364475675590848030
87086987551392711854517078544161852424320693150332
59959406895756536782107074926966537676326235447210
69793950679652694742597709739166693763042633987085
41052684708299085211399427365734116182760315001271
65378607361501080857009149939512557028198746004375
35829035317434717326932123578154982629742552737307
94953759765105305946966067683156574377167401875275
88902802571733229619176668713819931811048770190271
25267680276078003013678680992525463401061632866526
36270218540497705585629946580636237993140746255962
24074486908231174977792365466257246923322810917141
91430288197103288597806669760892938638285025333403
34413065578016127815921815005561868836468420090470
23053081172816430487623791969842487255036638784583
11487696932154902810424020138335124462181441773470
63783299490636259666498587618221225225512486764533
67720186971698544312419572409913959008952310058822
95548255300263520781532296796249481641953868218774
76085327132285723110424803456124867697064507995236
37774242535411291684276865538926205024910326572967
23701913275725675285653248258265463092207058596522
29798860272258331913126375147341994889534765745501
18495701454879288984856827726077713721403798879715
38298203783031473527721580348144513491373226651381
34829543829199918180278916522431027392251122869539
40957953066405232632538044100059654939159879593635
29746152185502371307642255121183693803580388584903
41698116222072977186158236678424689157993532961922
62467957194401269043877107275048102390895523597457
23189706772547915061505504953922979530901129967519
86188088225875314529584099251203829009407770775672
11306739708304724483816533873502340845647058077308
82959174767140363198008187129011875491310547126581
97623331044818386269515456334926366572897563400500
42846280183517070527831839425882145521227251250327
55121603546981200581762165212827652751691296897789
32238195734329339946437501907836945765883352399886
75506164965184775180738168837861091527357929701337
62177842752192623401942399639168044983993173312731
32924185707147349566916674687634660915035914677504
99518671430235219628894890102423325116913619626622
73267460800591547471830798392868535206946944540724
76841822524674417161514036427982273348055556214818
97142617910342598647204516893989422179826088076852
87783646182799346313767754307809363333018982642090
10848802521674670883215120185883543223812876952786
71329612474782464538636993009049310363619763878039
62184073572399794223406235393808339651327408011116
66627891981488087797941876876144230030984490851411
60661826293682836764744779239180335110989069790714
85786944089552990653640447425576083659976645795096
66024396409905389607120198219976047599490197230297
64913982680032973156037120041377903785566085089252
16730939319872750275468906903707539413042652315011
94809377245048795150954100921645863754710598436791
78639167021187492431995700641917969777599028300699
15368713711936614952811305876380278410754449733078
40789923115535562561142322423255033685442488917353
44889911501440648020369068063960672322193204149535
41503128880339536053299340368006977710650566631954
81234880673210146739058568557934581403627822703280
82616570773948327592232845941706525094512325230608
22918802058777319719839450180888072429661980811197
77158542502016545090413245809786882778948721859617
72107838435069186155435662884062257473692284509516
20849603980134001723930671666823555245252804609722
53503534226472524250874054075591789781264330331690
So...why does the array need to be [100]x[50]? Why does [99]x[50]
cause so many issues?
100 is the size you allocate, the indices go from 0 to 99 (99 + 1 = 100 ).
When you only allocate 99 you're missing the last line.
Since you're using a C string to handle the fifty digits, you have to get 1 extra char to terminate the string.
char input[100][51];
for (int i = 0; i != 100; ++i) /* 100 entries */
{
/* read your 50 digits normally here */
input[i][50] = '\0'; /* remember to terminate the string */
}
Im currently learning C through random maths questions and have hit a wall. Im trying to read in 1000 digits to an array. But without specifiying the size of an array first i cant do that.
My Answer was to count how many integers there are in the file then set that as the size of the array.
However my program returns 4200396 instead of 1000 like i hoped.
Not sure whats going on.
my code: EDIT
#include <stdio.h>
#include <stdlib.h>
int main (void)
{
FILE* fp;
const char filename[] = "test.txt";
char ch;
int count = 0;
fp = fopen(filename, "r");
if( fp == NULL )
{
printf( "Cannot open file: %s\n", filename);
exit(8);
}
do
{
ch = fgetc (fp);
count++;
}while (ch != EOF);
fclose(fp);
printf("Text file contains: %d\n", count);
return EXIT_SUCCESS;
}
test.txt file:
731671765313306249192251196744265747423553491949349698352031277450632623957831801698480186947885184385861560789112949495459501737958331952853208805511
125406987471585238630507156932909632952274430435576689664895044524452316173185640309871112172238311362229893423380308135336276614282806444486645238749
303589072962904915604407723907138105158593079608667017242712188399879790879227492190169972088809377665727333001053367881220235421809751254540594752243
525849077116705560136048395864467063244157221553975369781797784617406495514929086256932197846862248283972241375657056057490261407972968652414535100474
821663704844031998900088952434506585412275886668811642717147992444292823086346567481391912316282458617866458359124566529476545682848912883142607690042
242190226710556263211111093705442175069416589604080719840385096245544436298123098787992724428490918884580156166097919133875499200524063689912560717606
0588611646710940507754100225698315520005593572972571636269561882670428252483600823257530420752963450
Any help would be great.
You forgot to initialize count, so it contains random garbage.
int count = 0;
(But note that with this change it's still not going to work, since %d in a scanf format means read as many digits as you find rather than read a single digit.)
Turn on your compiler's warnings (-Wall), it will tell you that you didn't initialize count, which is a problem: it could contain absolutely anything when your program starts.
So initialize it:
int count = 0;
The other problem is that the scanfs won't do what you want, at all. %d will match a series of digits (a number), not an individual digit. If you do want to do your counting like that, use %c to read individual characters.
Another approach typically used (as long as you know the file isn't being updated) is to use fseek/ftell to seek to the end of the file, get the position (wich will tell you its size), then seek back to the start.
The fastest approach though would be to use stat or fstat to get the file size information from the filesystem.
If you want number of digits thin you tave to do it char-by-char e.g:
while (isdigit(fgetc(file_decriptor))
count++;
Look up fgetc, getc and scanf in manpages, you don't seem to understand whats going on in your code.
The way C initializes values is not specified. Most of the time it's garbage. Your count variable it's not initialized, so it mostly have a huge value like 1243435, try int count = 0.
I have a file called points.dat which reads something like:
5
2 5
-1 18
0 6
1 -1
10 0
The first number is how many ordered pairs there are. The next 5 lines contain those ordered pairs. What can I do to read in the first number, determine how many points there are (from here I can malloc an array of structs to store the points in).
My problem is that fgetc doesn't really do the job here. What if the first number is two digits? Say the first number is 10. fgetc will only retrieve the '1'. Also, fgets doesn't really work, since you need to supply it the length of the amount of characters you want to read in. The same applies for fscanf.
The real trouble comes in when it's time to retrieve the ordered pairs. I have no idea how to do this either. My only thoughts so far is look at a line: if it sees non-spaces or non-'\n's, it will read in the number as the x coordinate of point 1. Loop. Get y coordinate. Once it hits a '\n', it will now move on to the next line, and begin looking for values to store in the next struct in the array of structs.
(While doing this, I also need to be sure atoi can convert all of these into integers... ).
If anyone has any ideas to help, they are appreciated.
For the first line use int numValuesRead = fscanf(file, "%d", &totnums);
Then, use numValuesRead = fscanf(file, "%d %d", &num1, &num2); to read the other lines.
fscanf returns the number of value read. You should always check it.
#include <stdio.h>
#include <stdlib.h>
typedef struct {
int x, y;
} Point;
int main ()
{
int numOf;
Point *myPoints = NULL;
FILE *myfile = fopen ("myfile.txt","r");
if (myfile == NULL)
perror ("Error opening file"); //or return 1;
else
{
fscanf(myfile, "%d", &numOf);
myPoints = (Point *)malloc(sizeof(Point) * numOf);
while ( !feof (myfile) && numOf-- )
{
fscanf(myfile, "%d %d", &(myPoints[numOf].x), &(myPoints[numOf].y));
}
}
fclose(myfile);
//Do stuff with array
free ((void *)myPoints);
getchar();//Press enter to close debugger etc.
return 0;
}
Sorry for the delay.
I have the following in a text file called: values.txt
1 4
2.5 3.76
122 10
277.543
165.4432
I am trying to read the content of this text file, and add each two pairs together and output the result ...
the output would be something like this :
1 Pair:(1, 4) = 5
2 Pair:(2.5, 3.76)= 6.26
and so on ..
I am opening the file like this
int c;
FILE myfile;
myfile= fopen("values.txt", "r");
if ( myfile == NULL ) {
printf("Cannot open TEXT file\n");
return 1;
}
double aa,bb;
while ( (c = getc(myfile) ) != EOF ) {
// HERE SHOULD I DO THE OUTPUT BUT HOW?
}
Any help is really appreciated ..
Language = C
The following code does what you expect. myfile should be declared as FILE*. fopen returns a pointer to FILE structure. If the file is very large, I would recommend reading in buffers of big size (eg: 65535 etc) and parse it char by char and convert it to float values. It reduces system call overhead which takes more time than processing text to float values.
#include <stdio.h>
#include <string.h>
main(int argc, char *argv[])
{
FILE* myfile;
myfile = fopen("values.txt", "r");
if ( myfile == NULL ) {
printf("Cannot open TEXT file\n");
return 1;
}
double aa,bb;
while (2 == fscanf(myfile, "%lf %lf", &aa, &bb)) {
printf("%lf\n", aa+bb);
}
return 0;
}
For this simple task, use double a, b;
if (fscanf(myfile, "%lf %lf", &a, &b) == 2)
printf("%f + %f = %f\n", a, b, a+b);.
looks like a homework problem but fscanf can read the string into a variable like:
int n;
fscanf (myfile,"%d",&n);
You haven't shown what you need as output for the single-value lines, but this looks like a case for fgets() and sscanf(), unless you really want the two lines with a single value to be processed as a unit.
char buffer[256];
int rownum = 0;
while (fgets(buffer, sizeof(buffer), myfile) != 0)
{
double aa, bb;
int n = sscanf(buffer, "%lf %lf", &aa, &bb);
if (n == 2)
printf("%d Pair:(%g, %g) = %g\n", ++rownum, aa, bb, aa+bb);
else if (n == 1)
printf("%d Solo:(%g) = %g\n", ++rownum, aa, aa);
else
{
printf("Failed to find any numbers in <<%s>>\n", buffer);
}
}
If you used fscanf(myfile, "%g %g", &aa, &bb), then it would read over newlines (they count as white space) looking for numbers, so it would read one number from one line, and the second from another line. This is not usually what people are after (but when it is what you need, it is extremely useful). Error recovery with fscanf() tends to be more fraught than with fgets() and sscanf().
its in c++ sorry :( i dont know c
this is a very simple logic code for simple minde :D im a begineer too, i havent tested this prog so sorry if something goes wrong but exactly
on a same principle was working my parser and it worked fine. so this is a true method. not very efficent but...
do not use this program straight away, understand it's logic this will help you alot. copying that wont give you anything
...parser tutors are so rare....
int x=0;
char ch = 'r'; //i'v used this equasion to avoid error on first ckeck of ch.
it must be filled by something when program starts.
char bigch[10];
int checknumber = 0;
float firstnumber = 0;
float secondnumber = 0;
float result=0;
void clearar(char frombigar[10], int xar) //this function gets bigch as a reference which means that eny
changes made here, will directly affect bigch itself.
ths function gets the actual length of array and puts spaces
in bigch's every element to zero out numbers. we need to clear
bigch of any previous numbers. down below you'l see why i needed this.
'xar' is the x from main function. its here to tell our cleaner the
true length of filled bigar elements.
{
for (int i=0; i
}
}
int main()
{
<------------------- //here you add file opening and reading commands
while(!myfile.eof()) //while end of txt file have not been reached
{
ch=myfile.get(); //gets each letter into ch, and make cursor one step
forward in txt file for further reading.
get() does cursor forwarding automatically
if (ch!= " ") //i used space as an indicator where one number ends
//so while space havent been reahced, read letters.
{ bigch[x] = ch; //get read letter into bigch array.
x++; //icrement bigch array step
}
else
if(ch == " ") //if space is reached that means one number has ended and
{ im trying to set a flag at that moment. it will be used further.
checknumber++; the flag is simple number. first space will set checknumber to 1
second space will set it to 2. thats all.
}
if (checknumber == 1) //if our checknumber is 1, wich means that reading
of first number is done, lets make one whole float
from that bigch array.
{ firstnumber = atof(bigch); //here we get bigch, atof (array to float) command converts
bigch array into one whole float number.
clearar(bigch,x); //here we send bigch and its element step into function where
bigch gets cleaned because we dont want some ghost numbers in it.
abviously clearar function cleans bigch int main function aswell,
not only in it's teritory. its a global cleaning :)
}
else if (checknumber ==2) //here we do the same but if flag is 2 this means that two spaces
had been passed and its time to convert bigch into secondnumber.
{ secondnumber = atof(bigch); //same method of converting array into float (it hates other
not number letters, i mean if its a number its fine. if in your text
was 'a' or 's' in that case atof will panic hehe.. )
clearar(bigch,x); //same thing, we send bigch to cleaner function to kill any numbers
it, we get one space letter ( " " ) into each element of bigch.
}
checknumber = 0; if both two numbers had been read out and converted. we need to reset
space flagger. and start counting form 0; for next pair numbers.
result = firstnumber+secondnumber; well here everything is clear.
}
}