Get numbers only from a text file using c - c

/edited/
I'm new here.
I have a text file that reads:
6
<cr>
R 0
R 1
R 4
R 36
R 0
R 4
This is what I have. I want to read each line into an array so that I can convert that array into an integer so I can print only the numbers of whichever line I want later.
#include <stdio.h>
#include <conio.h>
#include <math.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
int main()
{
FILE *fr; /*declares file pointer*/
int i, j, num[32];
char array[32][32], input_file[32], line[32];
printf("Enter file: ");
fflush(stdin);
scanf("%s", input_file);
fr = fopen(input_file, "r");
for(i=0;i<32;i++)
for(j=0;j<32;j++){
array[i][j] = \'0';
}
for(i=0;i<32;i++){
line[i] = '\0';
}
if(fr != NULL){
while(fgets(line, sizeof(line), fr) != NULL){
strcpy(array[i],line);
num[i] = atoi(array[i]);
i++;
printf("%d\n", num[i]);
}
}fclose(fr);
else{
perror(input_file);
}
}
I'm not getting any errors but it isn't printing the right thing; this is what it prints:
-370086
-370086
-370086
-370086
-370086
-370086
-370086
-370086
Can anyone explain to me what is going wrong?

I think I'd handle this a bit differently. Though you haven't stated it explicitly, I'm going to assume that the first number is telling us how many more lines of letters/numbers we're going to read (not including the blank line). So, we want to read that, then read the rest of the lines, ignoring any leading non-digits, paying attention only to the numbers.
If that's correct, we can simplify the code somewhat:
int num_lines;
int i;
int *numbers;
fscanf(infile, "%d", &num_lines); // read the number of lines.
numbers = malloc(sizeof(int) * num_lines); // allocate storage for that many numbers.
// read that many numbers.
for (i=0; i<num_lines; i++)
fscanf(infile, "%*[^0123456789]%d", numbers+i);
// the "%*[^0123456789]" ignores leading non-digits. The %d converts a number.

There are several issues:
You're never setting input_file to anything, so you seem to be opening a random file.
You're double-using i in the nested loops.
You're not showing array at all, so it's impossible to tell how it's declared.
You are increasing the loop index before using it to print the number, so you're always "missing" and printing the number in the next (not yet written) slot.
You should use memset() to clear the arrays if you're worried. There's no need to clear arrays that are going to be overwritten, such as line which is written to by fgets().

Assuming array is a char array, when you do:
...
strcpy(array[i],line);
num[i] = atoi(array[i]);
...
Your actually converting the entire line and not the integer in it. You should consider using fscanf, or at least search for the integer inside the line variable and convert it.
Doing atoi(array[i]) is the same as atoi("R 32\n") for example.

Related

Storing String Inside a String?

My problem is when I try to save the string (series[0]) Inside (c[0])
and I display it, it always ignore the last digit.
For Example the value of (series[0]) = "1-620"
So I save this value inside (c[0])
and ask the program to display (c[0]), it displays "1-62" and ignores the last digit which is "0". How can I solve this?
This is my code:
#include <stdio.h>
int main(void)
{
int price[20],i=0,comic,j=0;
char name,id,book[20],els[20],*series[20],*c[20];
FILE *rent= fopen("read.txt","r");
while(!feof(rent))
{
fscanf(rent,"%s%s%s%d",&book[i],&els[i],&series[i],&price[i]);
printf("1.%s %s %s %d",&book[i],&els[i],&series[i],price[i]);
i++;
}
c[0]=series[0];
printf("\n%s",&c[0]);
return 0;
}
The use of fscanf and printf is wrong :
fscanf(rent,"%s%s%s%d",&book[i],&els[i],&series[i],&price[i]);
Should be:
fscanf(rent,"%c%c%s%d",&book[i],&els[i],series[i],&price[i]);
You have used the reference operator on a char pointer when scanf expecting a char pointer, also you read a string to book and else instead of one character.
printf("1.%s %s %s %d",&book[i],&els[i],&series[i],price[i]);
Should be:
printf("1.%c %c %s %d",book[i],els[i],series[i],price[i]);
And:
printf("\n%s",&c[0]);
Should be:
printf("\n%s",c[0]);
c is an array of char * so c[i] can point to a string and that is what you want to send to printf function.
*Keep in mind that you have to allocate (using malloc) a place in memory for all the strings you read before sending them to scanf:
e.g:
c[0] = (char*)malloc(sizeof(char)*lengthOfString+1);
and only after this you can read characters in to it.
or you can use a fixed size double character array:
c[10][20];
Now c is an array of 20 strings that can be up to 9 characters long.
Amongst other problems, at the end you have:
printf("\n%s",&c[0]);
There are multiple problems there. The serious one is that c[0] is a char *, so you're passing the address of a char * — a char ** — to printf() but the %s format expects a char *. The minor problem is that you should terminate lines of output with newline.
In general, you have a mess with your memory allocation. You haven't allocated space for char *series[20] pointers to point at, so you get undefined behaviour when you use it.
You need to make sure you've allocated enough space to store the data, and it is fairly clear that you have not done that. One minor difficulty is working out what the data looks like, but it seems to be a series of lines each with 3 words and 1 number. This code does that job a bit more reliably:
#include <stdio.h>
int main(void)
{
int price[20];
int i;
char book[20][32];
char els[20][32];
char series[20][20];
const char filename[] = "read.txt";
FILE *rent = fopen(filename, "r");
if (rent == 0)
{
fprintf(stderr, "Failed to open file '%s' for reading\n", filename);
return 1;
}
for (i = 0; i < 20; i++)
{
if (fscanf(rent, "%31s%31s%19s%d", book[i], els[i], series[i], &price[i]) != 4)
break;
printf("%d. %s %s %s %d\n", i, book[i], els[i], series[i], price[i]);
}
printf("%d titles read\n", i);
fclose(rent);
return 0;
}
There are endless ways this could be tweaked, but as written, it ensures no overflow of the buffers (by the counting loop and input conversion specifications including the length), detects when there is an I/O problem or EOF, and prints data with newlines at the end of the line. It checks and reports if it fails to open the file (including the name of the file — very important when the name isn't hard-coded and a good idea even when it is), and closes the file before exiting.
Since you didn't provide any data, I created some random data:
Tixrpsywuqpgdyc Yeiasuldknhxkghfpgvl 1-967 8944
Guxmuvtadlggwjvpwqpu Sosnaqwvrbvud 1-595 3536
Supdaltswctxrbaodmerben Oedxjwnwxlcvpwgwfiopmpavseirb 1-220 9698
Hujpaffaocnr Teagmuethvinxxvs 1-917 9742
Daojgyzfjwzvqjrpgp Vigudvipdlbjkqjm 1-424 4206
Sebuhzgsqpyidpquzjxswbccqbruqf Vuhssjvcjjylcevcisdzedkzlp 1-581 3451
Doeraxdmyqcbbzyp Litbetmttcgfldbhqqfdxqi 1-221 2485
Raqqctfdlhrmhtzusntvgbvotpk Iowdcqlwgljwlfvwhfmw 1-367 3505
Kooqkvabwemxoocjfaa Hicgkztiqvqdjjx 1-466 435
Lowywyzzkkrazfyjuggidsqfvzzqb Qiginniroivqymgseushahzlrywe 1-704 5514
The output from the code above on that data is:
0. Tixrpsywuqpgdyc Yeiasuldknhxkghfpgvl 1-967 8944
1. Guxmuvtadlggwjvpwqpu Sosnaqwvrbvud 1-595 3536
2. Supdaltswctxrbaodmerben Oedxjwnwxlcvpwgwfiopmpavseirb 1-220 9698
3. Hujpaffaocnr Teagmuethvinxxvs 1-917 9742
4. Daojgyzfjwzvqjrpgp Vigudvipdlbjkqjm 1-424 4206
5. Sebuhzgsqpyidpquzjxswbccqbruqf Vuhssjvcjjylcevcisdzedkzlp 1-581 3451
6. Doeraxdmyqcbbzyp Litbetmttcgfldbhqqfdxqi 1-221 2485
7. Raqqctfdlhrmhtzusntvgbvotpk Iowdcqlwgljwlfvwhfmw 1-367 3505
8. Kooqkvabwemxoocjfaa Hicgkztiqvqdjjx 1-466 435
9. Lowywyzzkkrazfyjuggidsqfvzzqb Qiginniroivqymgseushahzlrywe 1-704 5514
10 titles read

Reading a data file - unwanted extra value at the end of array

I'm fairly new to programming so apologies for any silly errors/oversights.
I'm trying to write a program that reads a data file with 3 columns of numbers and puts them into arrays. I'd like to be handle files of up to, say 100 elements.
The issue is that after I read a data file which I know to contain 20 elements, an extra value or 0.00000 is slapped onto the end of each array, so it has written 21 values instead of the 20 I want.
My code looks like this:
#include <stdio.h>
#include <cpgplot.h>
#include <stdlib.h>
#include <math.h>
#define MAXELEMENTS 100
int main()
{
/*Declare variables*/
float volume[MAXELEMENTS], temp[MAXELEMENTS], pressure[MAXELEMENTS];
int cnt = 1;
int i;
FILE *f;
char headings[MAXELEMENTS];
char filename[100];
/*Prompt user for file name*/
printf("Please enter the name of the file: ");
scanf("%s", &filename);
f = fopen(filename, "r");
if(f == NULL)
{
printf("File not found\n");
exit(EXIT_FAILURE);
}
/* Buffer line to read the headings of the data*/
fgets(headings, MAXELEMENTS, f);
/* Read records from the file until the end is reached*/
while(!feof(f) && cnt<MAXELEMENTS){
if (fscanf(f, "%f %f %f\n", &volume[cnt], &temp[cnt], &pressure[cnt]) > 0) cnt++;
}
So when I print out the arrays I get the 20 values I want PLUS an unwated 0.000000 value at the end of each. This created a lot of problems later when I try and plot some of the data.
From the searching I've done here and elsewhere it looks like it is the while(!feof(f)... loop that's the problem.
I'd be really grateful if anyone can help me get arrays just containing the values in the .dat file.
Thanks
The array index beggin in 0 like in volume[0], that is, you initialize cnt=0; not 1.
Additionaly,
if (fscanf(f, "%f %f %f\n", &volume[cnt], &temp[cnt], &pressure[cnt]) > 0)
cnt++;
else
break;
This break will probably solve the problem.
EDIT:
The code i can use to print:
i =0; // here you begging actualy with 0 or 1? Is here alrready corrected?
while (i < cnt)
{ printf("%f\t %f\t %f\n", volume[i], temp[i], pressure[i]);
i++; ....
Is here allready corrected? Is not, you print one more from 0 to cnt-1, and enter from 1 to cnt-1. Only why at ende and not at begging of the array have you the 0? Anyway, cold you test initializing cnt to 0? Is this exactly what do you use?
Check out how you are printing out the array. Your indices might be off leading to a trailing 0.0 value. Also you should initialize cnt=0.

Char array must be bigger than necessary

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 */
}

Simple count how many integers are in file in C

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.

Read in Numbers from a File in C

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.

Resources