How to use fscanf() to read a file containing integer number? - c

I need to use fscanf() to read a file containing integers from multiple lines.
The first integer is useless on every line; the rest I need to read.
I am doing like this
do {
fscanf(fs1[0],"%d%c",&x,&y);
//y=fgetc(fs1[0]);
if(y!='\n') {
printf("%d ",x);
}
} while(!feof(fs1[0]));
but in vain. For example,
101 8 5
102 10
103 9 3 5 6 2
104 2 6 3 8 7 5 4 9
105 8 7 2 9 10 3
106 10 6 5 4 2 3 9 8
107 3 8 10 4 2
we have to read
8 5
10
9 3 5 6 2
2 6 3 8 7 5 4 9
8 7 2 9 10 3
10 6 5 4 2 3 9 8
3 8 10 4 2

AFTER you have read file in a string, (fgets)
you can use (strtok), to split string and then use
(sscanf) to read integer.
strtok :
char str[] ="- This, a sample string.";
char * pch;
printf ("Splitting string \"%s\" into tokens:\n",str);
pch = strtok (str," ,.-");
while (pch != NULL) {
printf ("%s\n",pch);
pch = strtok (NULL, " ,.-");
}
sscanf :
int number = 0;
if(sscanf(pch, "%d", &number) ;

You should use fgets() to read the file line by line and then parse the numbers using sscanf(). You can then skip the first number for each line just as you please.
Here is an example:
#include <stdio.h>
#include <string.h>
int main() {
char fname[] = "filename.txt";
char buf[256];
char *p;
/* open file for reading */
FILE * f = fopen(fname, "r");
/* read the file line-wise */
while(p = fgets(buf, sizeof(buf), f)) {
int x, i = 0, n = 0;
/* extract numbers from line */
while (sscanf(p+=n, "%d%n", &x, &n) > 0)
/* skip the first, print the rest */
if (i++ > 0)
printf("%d ", x);
printf("\n");
}
}
For reference:
http://linux.die.net/man/3/fgets
http://linux.die.net/man/3/sscanf

do{
fscanf(fs1[0], "%d%c",&x,&y);//ignore first data.
while(2==fscanf(fs1[0], "%d%c", &x, &y)){
printf("%d ", x);
ch = fgetc(fs1[0]);//int ch;
if(ch == '\n' || ch == EOF){
printf("\n");
break;
} else
ungetc(ch, fs1[0]);
}
}while(!feof(fs1[0]));

Related

Ignoring escape sequence in C

I need to enter a matrix of size NxN of integers.
My idea is to enter it as a sequence of chars into char array and proceed working with it.
Matrix is given into stdin all at once.
The problem is to ignore escape characters (e.g. "\n") and enter all NxN integers as one string where integers will be separated with space.
Matrix itself is copied from txt file.
Input must end when Enter key is pressed.
//en axample of what I'm trying to reach
char buff[512];
gets(buff);
/*1 2 9 10 25
4 3 8 11 24
5 6 7 12 23
16 15 13 14 22
17 18 19 20 21*/
printf("%s", buff);
/*1 2 9 10 25
4 3 8 11 24
5 6 7 12 23
16 15 13 14 22
17 18 19 20 21/*
I tried using gets but it ended reading symbols when "\n" is reached.
Initial code looks like this:
int main(){
int size;
printf("enter size of matrix >> ");
scanf("%d",&size);
int matrix[size][size];
char allNumbers[size][512];
for (int i = 0; i < size; i++){
fgets(allNumbers[i], 511, stdin);
}
printf("%s", allNumbers[2]);
return 0;
}
input:1 2 9 10 25\n 4 3 8 11 24\n 5 6 7 12 23\n 16 15 13 14 22\n 17 18 19 20 21\0
output:
1 2 9 10 25
Consider using one char array for input.
Generally do not use both scanf and fgets.
This uses fgets to read a line with the size and sscanf to parse the integer from the line.
The same array is used to read the lines pasted from the file.
The loop continues until an empty line is read.
It may be necessary to hit enter a few times to exit the loop.
This does not parse the integers from the file. sscanf can be used to accomplish that as well. strtol is another parsing option.
#include <stdio.h>
#include <stdlib.h>
int main ( void) {
char input[512] = "";
int size = 0;
int row = 0;
int col = 0;
int offset = 0;
int used = 0;
printf ( "enter size of matrix >> ");
fflush ( stdout);
if ( ! fgets ( input, sizeof input, stdin)) {
fprintf ( stderr, "problem fgets\n");
return 1;
}
if ( 1 != sscanf ( input, "%d", &size)) {
fprintf ( stderr, "problem sscanf for size\n");
return 2;
}
int matrix[size][size];
for ( row = 0; row < size; ++row) {
for ( col = 0; col < size; ++col) {
matrix[row][col] = 0;
}
}
row = 0;
printf ( "enter matrix values >> ");
while ( fgets ( input, sizeof input, stdin)){
if ( '\n' == input[0]) {
break;
}
printf ( "\nrow %d %s", row, input);
offset = 0;
if ( row < size) {
// parse integers from input;
}
++row;
}
for ( row = 0; row < size; ++row) {
for ( col = 0; col < size; ++col) {
printf ( "%4d ", matrix[row][col]);
}
printf ( "\n");
}
return 0;
}

Facing problems with the atoi function if used repeatedly

I have to find the frequency of digits {0,1,2,3,4,5,6,7,8,9} in a given string, I'm using atoi function to convert the character to an integer and I'm having problems with the atoi function when the input string is large (tried this with different test cases of varying length),
for example if the input string is
1v88886l256338ar0ekk
my code works properly and the answer is
1 1 1 2 0 1 2 0 5 0
where the 1st digit indicates the frequency of 0 and so on upto 9,
but if the input string is
9139f793308o0lo66h6vc13lgc697h0f6c32lu84445972k0o0l033od17c083yn5051d6j319hyo8j939n28d913015ns6zx5653x01211x12ch2526o65sg7xw6302141q9203s22l336319ll9yx4b597mr318a7943906750j4u152067nq83ne9f24thu96yd05173l47c803roxci45615f0w53i1sz913jj6za733l73tw6r66mq6p44sfhjr26h8e801z8zlcx2l1e65r2879xj3w3acv216196uq158o663y7oz2i5378v0v5w17762451t424352m23026r9o202i9785382o159e4gu1c8561157z5f1vqs5755465b8u728u956434mv944885li456628a994u7j5278m269n1pk8e46940q834h06il6h447888tr7ig72z10fe09k5g98h9bgt6z40v42s16pt6k3l3v45i83i01b9448g554741w766f2q7v31i085488h060e710p53076c6nm98pi946g8j2n6j8x29qa1ad48172y0u4818121p686bud89741201p54087u56g8scerv9pvhuo09re477zfb224i2c1325bj58jx4bk7b009f6446j5i95474p266i503r670n631x6940gwl71ejbx47imx576129248901765rnpu6l80084t0j1839f5y3409w2n403fu6ogw1170jmb6o5l520vg0703e0
upon reaching the end of the string the atoi function returns wrong values
for example,
my code uses atoi to convert char text to an integer and stores it into int num
at the beginning the function works fine,
text is 9 num is 9
text is 1 num is 1
text is 3 num is 3
text is 9 num is 9
text is 7 num is 7
text is 9 num is 9
text is 3 num is 3
text is 3 num is 3
text is 0 num is 0
text is 8 num is 8
text is 0 num is 0
.
.
.
and upon nearing the very end of the string the function returns
.
.
.
text is 2 num is 2
text is 4 num is 4
text is 0 num is 0
text is 3 num is 30
text is 6 num is 60
text is 1 num is 10
text is 1 num is 10
text is 7 num is 70
text is 0 num is 0
text is 6 num is 61
text is 5 num is 51
text is 5 num is 51
text is 2 num is 21
text is 0 num is 1
text is 7 num is 71
text is 0 num is 1
text is 0 num is 1
text is 3 num is 31
If I replace int num = atoi(&text) with int num = text - '0' my program works perfectly for all test cases,
so can someone please tell me what went wrong and whether I have used the function incorrectly.
Please keep in mind I just want to know why atoi didn't work, hence I'm not looking for replacements for the function.
I've included the snippet of my code below
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <ctype.h>
int main() {
int arr[10] = {0};
char text;
text = getchar();
while(text != EOF)
{
if(isdigit(text))
{
printf("text is %c ",text);
int num = atoi(&text);
printf("num is %d\n ",num);
for(int i =0; i<10;i++)
{
if(num==i)
{
arr[i]++;
//printf("arr[%d] is %d\n", i,arr[i]);
break;
}
}
}
text = getchar();
}
for(int i=0; i<10;i++)
{
printf("%d ",arr[i]);
}
return 0;
}
Thanks in advance for taking the time to read and answer my question
Per the atoi() documentation in the C standard:
The atoi, atol, and atoll functions convert the initial portion of the string pointed to by nptr to int, long int, and long long int representation, respectively.
Note the bolded part.
Given
char text;
this code invokes undefined behavior because the address passed to atoi() is not that of a string:
int num = atoi(&text);
One fix would be:
char text[2];
text[1] = '\0';
// getchar() returns int, not char, in order
// to handle EOF properly
int input = getchar();
while(input != EOF)
{
text[0] = input;
if(isdigit(text[0]))
{
printf("text is %s ",text);
int num = atoi(text);
That ensures that a string (a nul-terminated series of char) is passed to atoi().
you don't need atoi() since you are dealing with single characters, not with strings
getc()returns an int [0 .. 255 for actual characters, -1 for EOF]
you can avoid a lot of {} braces by using break and continue
#include <stdio.h>
#include <ctype.h>
int main() {
int arr[10] = {0};
int text, num;
while(1) {
text = getchar();
if (text == EOF) break;
if (!isdigit(text)) continue;
printf("text is %c ", text);
num = text - '0'
printf("num is %d\n ",num);
arr[num]++;
//printf("arr[%d] is %d\n", num, arr[num]);
}
for(int i=0; i<10;i++)
{
printf("%d ",arr[i]);
}
return 0;
}

C fscanf input format

I have an input file that contains lines of the following format:
%s %d %d %d %lf %lf ... %lf\n
where the number of double values is unknown, but for my calculations I accept only first 15 of them.
The problem I can't figure out is, when I get to the line like this:
City0 28 2 2016 1 2 3 4 5 6 7 8 9 10
City1 28 2 2016 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
City2 1 3 2016 1 2 3 4 5
and I correctly assign respective values to a certain structure, I get the following:
City0 28 2 2016 Number of measures: 10
City1 28 2 2016 Number of measures: 15
16 17 18 19 Number of measures: 1
City2 1 3 2016 Number of measures: 5
How do I read(to nowhere)/ignore everything until I get to the end of the line, and then start reading the next line as usual? I need the following output:
City0 28 2 2016 Number of measures: 10
City1 28 2 2016 Number of measures: 15
City2 1 3 2016 Number of measures: 5
I tried this but ain't got any more ideas:
i=0; char character;
while (fscanf(fp, "%s %d %d %d", c.name, &c[i].date.day,
&c[i].date.month, &c[i].date.year)==4 && i<number_of_cities) {
while (fscanf(fp, "%lf", &c[i].measures[j])==1 && j<15) {
j++;
}
if (j==15) {
while (fscanf(fp, "%s", character)!='\n') {}
}
c[i].mnum = j;
j=0;
i++;
}
You can use fscanf() to read in an entire line of input, use sscanf() to scan the first four values, and use sscanf() again in a loop to read the double values. The trick here is to use the %n directive to save the position of the next read location in the string.
Here is an example. Note that size_t is used for array indices, as this is an unsigned integer type that is guaranteed to hold any array index. Also note that there is some error-checking when opening the file, and when scanning the beginning of a line. If the initial elements of the line do not match expected values, the program exits with an error message. This error-checking could be tightened up a bit; for example, if the year is entered as a floating point value, such as 2016.0, the input will be accepted, but the values stored in measures[] will begin with the 0 following the decimal point.
#include <stdio.h>
#include <stdlib.h>
struct Data {
char name[1000];
struct {
int day;
int month;
int year;
} date;
size_t mnum;
double measures[15];
};
int main(void)
{
size_t i = 0, j = 0;
char buffer[1000];
char *read_ptr = buffer;
int n_read = 0;
size_t number_of_cities = 3;
struct Data c[number_of_cities];
FILE *fp;
if ((fp = fopen("datafile.txt", "r")) == NULL) {
fprintf(stderr, "Unable to open file\n");
exit(EXIT_FAILURE);
}
while (fgets(buffer, 1000, fp) != NULL) {
if (sscanf(buffer, "%s %d %d %d %n", c[i].name, &c[i].date.day,
&c[i].date.month, &c[i].date.year, &n_read) != 4) {
fprintf(stderr, "Incorrect input format\n");
exit(EXIT_FAILURE);
}
read_ptr += n_read;
while (sscanf(read_ptr, "%lf %n", &c[i].measures[j], &n_read) == 1 &&
j < 15) {
read_ptr += n_read;
++j;
}
c[i].mnum = j;
++i;
j = 0;
read_ptr = buffer;
if (i == number_of_cities) {
break;
}
}
for (i = 0; i < number_of_cities; i++) {
printf("%s %d %d %d Number of measures: %zu\n",
c[i].name,
c[i].date.day, c[i].date.month, c[i].date.year,
c[i].mnum);
for (j = 0; j < c[i].mnum; j++) {
printf("%5g", c[i].measures[j]);
}
putchar('\n');
}
return 0;
}
Program output using your example data as input:
City0 28 2 2016 Number of measures: 10
1 2 3 4 5 6 7 8 9 10
City1 28 2 2016 Number of measures: 15
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
City2 1 3 2016 Number of measures: 5
1 2 3 4 5

Read numbers from text file and use them as input

I have this text:
0 0 0 0 0 1
0 0 0 0 1 1
0 0 0 1 0 1
0 0 0 1 1 1
I want to read the first 5 numbers from each line and then use them as inputs in a function.
I'm new to c and have only accomplished this code that doesn't do much, if anything really.
int v,o;
FILE *mydata;
if ((mydata = fopen("testinputs.txt", "rt"))==NULL)
{
printf ("file can't be opened'\n");
exit(1);}
fclose(mydata);
How do i complete it?
Thank you.
Well, assuming your file is called "input.txt", then this is all you need to do:
#include <stdio.h>
#include <stdlib.h>
#define LINE_LEN 100
int main ( void )
{
char line[LINE_LEN];
int sum, i, read_cnt, numbers[5];//sum and i are there for my example usage
FILE *in = fopen("input.txt", "r");//open file
if (in == NULL)
{
fprintf(stderr, "File could not be opened\n");
exit( EXIT_FAILURE);
}
while((fgets(line, LINE_LEN, in)) != NULL)
{//read the line
//scan 5 numbers, sscanf returns the number of values it managed to extract
read_cnt = sscanf(
line,
"%d %d %d %d %d",
&numbers[0],
&numbers[1],
&numbers[2],
&numbers[3],
&numbers[4]
);
//check to see if we got all 5 ints
if (read_cnt != 5)
printf("Warning: only read %d numbers\n", read_cnt);//whoops
//just an example, let's add them all up
for (sum= i=0;i<read_cnt;++i)
sum += numbers[i];
printf("Sum of numbers was: %d\n", sum);
}
return EXIT_SUCCESS;
}
With this input.txt file:
1 2 3 4 5
2 2 2 2 2
1 23 2 3 4
12 23
This gives us the following output:
Sum of numbers was: 15
Sum of numbers was: 10
Sum of numbers was: 33
Warning: only read 2 numbers
Sum of numbers was: 35
That should be more than enough to get you started
Here is a small code to read character by character and store only the wanted numbers:
C Code:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int c; // Character read from the file
int cpt; // Counter (to get only 5 numbers per line)
int i,j; // Array indexes
int data[4][5]; // 2D integer array to store the data
FILE *f; // File
if ((f = fopen("file.txt", "r")) == NULL) // Open the file in "read" mode
{
printf ("file can't be opened'\n");
exit(255);
}
// Counter and indexes initialization
cpt=0;
i=0;
j=0;
// Read the file till the EOF (end of file)
while ((c = fgetc(f)) != EOF)
{
// If 5 numbers read, go to new line, first index in the data array and to the next line in the file
if(cpt==5)
{
i++;
cpt=0;
j=0;
while(c != '\n' && c != EOF)
c=fgetc(f);
}
// If a number is read, store it at the right place in the array
if(c>='0'&&c<='9')
{
// Convert character to integer (see ascii table)
data[i][j] = c-'0';
j++;
cpt++;
}
}
// Display the array
for(i=0;i<4;i++)
{
for(j=0;j<5;j++)
printf("%d ", data[i][j]);
printf("\n");
}
fclose(f);
}
And here is the output:
0 0 0 0 0
0 0 0 0 1
0 0 0 1 0
0 0 0 1 1
Now you can use your 2D array, for example if you want a variable a to have the 2nd line, 3rd number, you'd do : a = data[1][2]
Don't forget arrays start at index 0
Hope this helps...
It might help you:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
FILE *datafile;
int main()
{
char line[100],*ch;
int count;
datafile = fopen ( "my.txt", "r");
while ( fgets(line , sizeof line , datafile) != NULL )//fgets reads line by line
{
count = 0;
ch = strtok ( line , " ");
while ( count < 5 && ch != NULL )
{
printf("%d ",*ch - 48 );//*ch gives ascii value
//pass to any function
count++;
ch = strtok ( NULL, " ");
}
}
return 0;
}
The above program passes integer by integer.

How to read a multi line using fscanf

I want to read my data.txt file which looks like and store it in an array called buffer[i][j]
1 1 1 1
2 2 2 2
3 3 3 3
4 4 4 4
I am writing a code which looks like
#include"stdio.h"
#include"stdlib.h"
int main() {
FILE *fp1;
int i,j;
int buffer[4][4]={0};
fp1 = fopen("exact_enumerated_config_442_cub_mc","r");
for(i=0;i<4;i++) {
for(j=0;j<4;j++) {
fscanf(fp1,"%d", &buffer[i][j]);
}
// fscanf(fp1,"\n");
}
fclose(fp1);
for(i=0;i<4;i++) {
for(j=0;j<4;j++) {
printf("%d ",buffer[i][j]);
}
printf("\n");
}
}
but i get the output...
1 1 2 1
5 1 6 1
17 1 18 1
21 1 22 1
why????
Always check the result of fopen() to ensure the file has been opened.
Always check the result of fscanf() to ensure it was successful and prevent subsequent code processing variables that may not have been assigned a value (it returns the number of assignments made).
Add a leading space character to the format specifier to skip whitespace, including newline characters: " %d".
The code will treat a single line with sixteen ints the same as four lines with four ints. If it is important that the format of the file is four ints per line then read a single line using fgets() and then use sscanf() to extract the ints with the %n format specifier to ensure full buffer was processed:
int ints[4][4] = { { 0 } };
char buffer[1024];
for (int i = 0; i < 4 && fgets(buffer, 1024, fp); i++)
{
int pos;
if (sscanf(buffer,
"%d %d %d %d%n",
&ints[i][0],
&ints[i][1],
&ints[i][2],
&ints[i][3],
&pos) != 4 || pos != strlen(buffer) - 1)
{
fprintf(stderr, "Invalid format: <%s>\n", buffer);
exit(1);
}
}
Add space at the beginning of the string format it should be " %d" to avoid the newline problems
fscanf(fp1," %d", &buffer[i][j]);
BTW you could use the following code instead
for(i=0;i<4;i++) {
fscanf(fp1," %d %d %d %d", &buffer[i][0], &buffer[i][1], &buffer[i][2], &buffer[i][3]);
}
To get required output (1111,2222,...) change:
fp1 = fopen("exact_enumerated_config_442_cub_mc","r");
to:
fp1 = fopen("data.txt","r");
Clarification: when using fopen you should write the name of file you want to read. In you case you have to write data.txt, not exact_enumerated_config_442_cub_mc...
There is no file with this name, moreover there is no any data like 1 1 1 1, 2 2 2 2, 3 3 3 3, 4 4 4 4...
For more detailes visit:
wikibooks.org/wiki/C_Programming/C_Reference/stdio.h/fopen
Here is your "modified" (excess/waste/extra { } removed and data.txt is written) code that gives you required output: 1 1 1 1, 2 2 2 2, 3 3 3 3, 4 4 4 4.
It prints the array named buffer. It means that...
...data was successfully copied! from "data.txt" to buffer[4][4]:
#include"stdio.h"
#include"stdlib.h"
int main()
{
FILE *fp1;
int i,j;
int buffer[4][4];
for ( i = 0; i < 4; i++ )
for ( j = 0; j < 4; j++ )
buffer[i][j] = 0;
fp1 = fopen("data.txt","r");
for(i=0; i<4; i++)
for(j=0; j<4; j++)
fscanf(fp1,"%d", &buffer[i][j]);
fclose(fp1);
for(i=0; i<4; i++)
{
for(j=0; j<4; j++)
printf("%d ",buffer[i][j]);
printf("\n");
}
return 0;
}
P.S.
If data.txt will contain not
1 1 1 1
2 2 2 2
3 3 3 3
4 4 4 4
but
1 1 1 1
2 2 2 2
3 3 3 3
4 444 // the last two elements are absent
the program will read 1-st, 2-nd and 3-rd line properly, and the output of the 4-th line will be
4 444 0 0
It prints 4, then 444, and then 0 and 0: the last two elements are '0's because buffer had been initialized by zeros, so all elements changed their values, but the last two remained to be zeros.
You have said you want to read data.txt then why are you opening the file exact_enumerated_config_442_cub_mc
Try changing this
fp1 = fopen("exact_enumerated_config_442_cub_mc","r");
to
fp1 = fopen("data.txt","r");

Resources