Reading combinations of string and integer from file in C - c

I am novice to C langugage, so please bear with me. I've tried to read a file which contains strings but output obtained is single character.
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#define CALLOC(num, type) ((char*)calloc (num, sizeof(char)))
#define FREE(addr) (free((void*) (addr)))
int i, count;
char *x, *y, *z;
int main (void)
{
FILE *stream;
if ( (stream = fopen ( "test.txt", "r" )) == NULL )
{ printf ("Cannot read the new file\n");
exit (1);
}
count = 3;
x=CALLOC(count, char);
y=CALLOC(count, char);
z=CALLOC(count, char);
for ( i=0; i<count; i++ )
{ fscanf (stream,"%c %c %c", &x[i], &y[i], &z[i]);
printf ("\n %d %c %c %c ", i, x[i], y[i], z[i]);
}
FREE(x);
FREE(y);
FREE(z);
fclose (stream);
}
Input test.txt file contains
1 ab 1
2 aa 5
1 cc 1
current output
0 1 a b
1 1 2
2 a a
Expected output
0 1 ab 1
1 2 aa 5
2 1 cc 1
I doubt whether I should use a character array but it seems not working and I feel reading a int using char is acceptable. Here I require the expected output, for this any method/suggestion is appreciated.

%c reads in only one char. So it's not going to read ab as a single char. Your lines in file and your formats don't correctly to read an entire line.
A simple approach is to use fgets() and print the entire line:
char line[256];
i = 0;
while(fgets(line, sizeof line, stream))
{
printf ("%d %s", i, line);
i++;
}
By the way, macros for calloc and free are unnecessary. They really don't make the code any easier to read than directly using those functions.
And the casts in them are also unnecessary.

The problem is you have the scan file. %c read a 8bit value. You scanned 3 char, but the file is contain 4 characters. If you don't use to be the value of the x, y, z I don't understand why use malloc.
Here a working source:
#include <stdio.h>
#include <stdlib.h>
int main() {
int count,i;
char w,x,y,z;
FILE *stream;
if((stream = fopen("test.txt","r")) == NULL) {
printf("Cannot read the new file\n");
return 1;
}
count = 3;
for(i=0;i<count;++i) {
fscanf(stream,"%c %c%c %c\n",&w,&x,&y,&z);
printf("%d %c %c%c %c\n",i,w,x,y,z);
}
return 0;
}

for ( i=0;i<count; i++ )
{
fscanf (stream,"%s %s %s", x, y, z);
printf ("\n %d %s %s %s ", i, x, y, z);
}
You can modify your loop to this.This loop will read file until end of file and you have to use %s as ab is a string not charater so it can't be stored in a char variable.

Related

How to read data from a text file and store it in a variable in C language?

I am trying to read a text file in C. The name of the file is test.txt and has the following kind of format.
Nx = 2
Ny = 4
T = 10
I have written this C code to read the values of Nx, Ny, and T which is 2, 4, and 10 respectively.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void main()
{
double Data[3]; // I'm interested in this information
char junk1, junk2; // junk variables to avoid first two characters
FILE * file = fopen("test.txt", "r"); // open file
for(int i = 0; i < 3; i++) // each loop will read new line of file; i<3 for 3 lines in file
{
fscanf(file, "%s %s %lf\n", &junk1, &junk2, &Data[i]); //store info in Data array
printf("%f\n", Data[i]); // print Data, just to check
}
fclose(file);
int Nx; // store data in respective variables
int Ny;
double T;
Nx = Data[0];
Ny = Data[1];
T = Data[2];
printf("Value of Nx is %d\n", Nx); // Print values to check
printf("Value of Ny is %d\n", Ny);
printf("Value of T is %f\n", T);
}
But got this as an output. This output is wrong as the values of Nx, Ny, and T are not matching with the data given above.
Please help me to solve this problem.
junk1 and junk2 should be arrays of char to be able to store strings.
But since it is junk you could simply not store it anywhere by using * in the fscanf conversion specifiers:
fscanf(file, "%*s %*s %lf\n", &Data[i]);
fscanf documentation:
https://en.cppreference.com/w/c/io/fscanf
Your program makes strong assumptions about the input file:
the file "test.txt" exists in the current directory and can be read
it contains at least 3 settings, in the order Nx, Ny, T.
It has problems too:
reading a string with %s into a single character variable junk1 will cause undefined behavior, same for junk2, because fscanf() will attempt to store all characters from the string plus a null terminator at the destination address, overwriting other data with potentially catastrophic consequences.
main has a return type int.
Here is a more generic approach:
#include <stdio.h>
#include <string.h>
int main() {
int Nx = 0, Ny = 0;
double T = 0;
int has_Nx = 0, has_Ny = 0, has_T = 0;
char buf[80];
FILE *file;
if ((file = fopen("test.txt", "r")) == NULL) {
fprintf(stderr, "cannot open test.txt\n");
return 1;
}
while (fgets(buf, sizeof buf, file)) {
if (buf[strspn(buf, " ")] == '\n') /* accept blank lines */
continue;
if (sscanf(buf, " Nx = %d", &Nx) == 1)
has_Nx = 1;
else
if (sscanf(buf, " Ny = %d", &Ny) == 1)
has_Ny = 1;
else
if (sscanf(buf, " T = %lf", &T) == 1)
has_T = 1;
else
fprintf(stderr, "invalid line: %s", buf);
}
fclose(file);
// Print values to check
if (has_Nx)
printf("Value of Nx is %d\n", Nx);
if (has_Ny)
printf("Value of Ny is %d\n", Ny);
if (has_T)
printf("Value of T is %g\n", T);
return 0;
}

how to read multiple lines of a file in c

Am trying to read a file which contains the coordinate values for my code. each time i use scanf it reads only the first line...(60,70,200,200). my question is how do i make my code read all the contents of my file and print it out on the screen.here is my code and file.
FILE.txt:
S (60,70)(200,200)
S (30,40)(100,200)
S (10,20)(80,10)
S (60,400)(700,200)
S (160,70)(240,20)
MY CODE:
#include <stdio.h>
int a;
int b;
int c;
int d;
int data[4][5];
int main ( int argc, char *argv[] )
{
if ( argc != 2 ) /* argc should be 2 for correct execution */
{
/* We print argv[0] assuming it is the program name */
printf( "usage: %s filename", argv[0] );
}
else
{
// We assume argv[1] is a filename to open
FILE *file = fopen( argv[1], "r" );
/* fopen returns 0, the NULL pointer, on failure */
if ( file == 0 )
{
printf( "Could not open file\n" );
}
else
{
int i,j;
for (j=0; j < 5; j++)
{
for (i=0; i < 4; i++) {
fscanf(file, "S (%d,%d)(%d,%d)", &a, &b, &c, &d);
data[i][j] = (a, b, c, d);
printf("%d,%d,%d,%d\n",a, b, c, d);
}
}
fclose( file );
}
}
}
You must check the return value of I/O calls such as fscanf(). If it's failing, it will return 0 without changing your variables.
Also, this:
data[i][j] = (a, b, c, d);
Doesn't make a lot of sense in C. Remember that C doesn't have tuples like Python. The above is equivalent to:
data[i][j] = d;
Use while loop:
const int NumberOfValuesIamGoingToReadAtOnce = 4;
while (fscanf(file, "S (%d,%d)(%d,%d)", &a, &b, &c, &d) == NumberOfValuesIamGoingToReadAtOnce)
{
// do some actions with obtained values
}
as fscanf returns number of read values by return value you can judge if EOF achieved or file wrongly written
Try reading the newline as well:
fscanf(file, "S (%d,%d)(%d,%d)\n", &a, &b, &c, &d);
But why the double loop: you're already reading 4 values at the same time.
Instead, make it one infinite loop and check whether you've read 4 values; break when you did not read 4 values.
Lastly:
data[i][j] = (a, b, c, d);
does not make any sense (as any decent compiler warning will tell you). This, instead, may be where you want your second loop: around the assignement, not the scanf statement.
declar data[4][5] to data[5][4]
modify the loop
for (i=0; i < 5; i++)
{
fscanf(file, "S (%d,%d)(%d,%d)", &a, &b, &c, &d);
data[i][0] =a;
data[i][1] =b;
data[i][2] =c;
data[i][3] =d;
printf("%d,%d,%d,%d\n",a, b, c, d);
}
If you are going to fscanf(), you have to careful as you have to make sure the file is in correct format with exact number of spaces like how read in fscanf().
I would recommend using fgets() then reading numbers from the string using sscanf().
data[i][j] = (a, b, c, d);
This line doesn't do what you think it does. You really don't need another loop as you read all numbers in a line at once.
for (j=0; j < 5; j++)
{
fscanf(file, "S (%d,%d)(%d,%d)", &a, &b, &c, &d);
data[j][0] = a;
data[j][1] = b;
data[j][2] = c;
data[j][3] = d;
printf("%d,%d,%d,%d\n",a, b, c, d);
}
}
And change data[4][5] to data[5][4];
I used fgets to read file line per line and I used sscanf instead of fscanf
#include <stdio.h>
#include <string.h>
int data[4][5];
char line[128];
int main ( int argc, char *argv[] )
{
if ( argc != 2 ) /* argc should be 2 for correct execution */
{
/* We print argv[0] assuming it is the program name */
printf( "usage: %s filename", argv[0] );
}
else
{
// We assume argv[1] is a filename to open
FILE *file = fopen( argv[1], "r" );
/* fopen returns 0, the NULL pointer, on failure */
if ( file == 0 )
{
printf( "Could not open file\n" );
}
else
{
int i=0;
line[0] = 0;
while(fgets(line,sizeof(line),file))
{
sscanf(line, "S (%d,%d)(%d,%d)", &data[i][0], &data[i][1], &data[i][2], &data[i][3]);
printf("%d,%d,%d,%d\n", data[i][0], data[i][1], data[i][2], data[i][3]);
i++;
}
fclose( file );
}
}
}

Parse string " comes from a file " to integer

I am making a program in C that reads a line from file and displays this line on screen
My homework requires that the file must get a number from the file and make some operations on it.
I get the file content and put it in an array:
while ( fgets ( line, sizeof line, file ) != NULL )
{
strcpy(arra[i], line);
printf("array ----> %d \n", arra[i]);
i++;
}
how can I parse this content to int ?
If line is a char*, you can use atoi to convert it to an integer.
printf("array ----> %d \n", atoi(line));
you can use atoi()
int x = atoi("string");
From your code sample
while ( fgets ( line, sizeof line, file ) != NULL )
{
strcpy(arra[i], line);
printf("array ----> %d \n", atoi(arra[i]));
i++;
}
#include <stdio.h>
#include <stdlib.h>
#define MAX_DATA_SIZE 10
int main(){
FILE *file;
char line[128];
int array[MAX_DATA_SIZE];
int i,count,sum;
file = fopen("data.txt","r");
/* data.txt:
100
201
5
-6
0
*/
for(i=0; NULL!=fgets(line, sizeof(line), file); ++i){
if(i == MAX_DATA_SIZE){
fprintf(stderr,"exceeded the size of the array.\n");
exit(EXIT_FAILURE);
}
array[i]=atoi(line);
}
fclose(file);
/*some operations */
count = i;
sum = 0;
for(i=0;i<count;++i)
sum += array[i];
printf("%d\n",sum);
return 0;
}

C Read until end of file

I currently have code that reads 4 lines and I want to be able to change that until EOF or my MAX const int value. I can not get the !EOF to work right and was wondering how would I change my code to accomplish this?
Thanks in advance
#include <stdio.h>
struct record{
char name[2];
int arrival_time;
int job_length;
int job_priority;
};
const int MAX = 40;
int main(void)
{
struct record jobs[MAX];
int i = 0;
int j;
FILE *f = fopen("data.dat","rb");
while (fscanf(f, "%s %d %d %d", &jobs[i].name, &jobs[i].arrival_time,
&jobs[i].job_length, &jobs[i].job_priority) == 4 && i < MAX)
i++;
for (j = 0; j < i; j++)
printf("%s %d %d %d\n", jobs[j].name, jobs[j].arrival_time,
jobs[j].job_length, jobs[j].job_priority);
fclose(f);
return(0);
}
Something like
while (fscanf(f, " %s ", &etc) != EOF) {
}
Then use feof(f) to check if it was a fscanf error or actually EOF.
Your code seems to do what you want, except:
char name[2];
Names will probably be longer than 1 character.
FILE *f = fopen("data.dat","rb");
You seem to be reading text ("r") file, not binary ("rb").
&jobs[i].name should be jobs[i].name
You need to change the order of the tests in your while() loop - you must test i < MAX before calling fscanf(), or else you'll potentially call it one too many times (you should also be passing jobs[i].name without the & to fscanf):
while (i < MAX && fscanf(f, "%s %d %d %d", jobs[i].name, &jobs[i].arrival_time,
&jobs[i].job_length, &jobs[i].job_priority) == 4)
Personnaly, I would code like this:
for(i=0 ; i<MAX ; ++i) {
fscanf(f, "%s %d %d %d", &jobs[i].name, &jobs[i].arrival_time,
&jobs[i].job_length, &jobs[i].job_priority);
if(ferror(f) || feof(f)) break;
}
The key point is that, at the best of my knowledge, you cannot know that a file is come to end without trying to read it. That is the reason why I check feof() and ferror() after having read data.
At the end of the loop, the variable i contains the number of read data

how to make a BufferedReader in C

I am really new programming in C. How can I do the same in C, maybe in a more simple way than the one I do in Java?
Each line of the input has two integers: X and Y separated by a space.
12 1
12 3
23 4
9 3
InputStreamReader in = new InputStreamReader(System.in);
BufferedReader buf = new BufferedReader(in);
int n;
int k;
double sol;
String line = "";
line = buf.readLine();
while( line != null && !line.equals("")){
String data [] = line.split(" ");
n = Integer.parseInt(data[0]);
k = Integer.parseInt(data[1]);
calculus (n,k);
line = buf.readLine();
}
Use fgets() to read a line of text and sscanf() to parse it:
#include <stdio.h>
int main(void)
{
int n, k;
char line[64]; // adjust size as necessary
while(fgets(line, sizeof line, stdin) && sscanf(line, "%d %d", &n, &k) == 2)
printf("n=%d, k=%d\n", n, k); // dummy code
return 0;
}
Using scanf() alone to read directly from stdin might be possible with scansets, but it's not as easy as it looks because whitespace characters (including newlines) are skipped.
No compiler, so please fix as needed. Also the variable decalrations are C++ style
#include <stdio.h>
...
while (!feof(stdin)) {
int n = 0, k = 0;
if (scanf("%d %d\n", &n, &k) != 2) continue;
// do something with n and k
}
C++ solution (with streams) may be simpler still
fscanf(filehandle, "%d %d\n", n, k);
The file variable is called FILE
To open a file use fopen()
Reading and writing are done with fgets() and fputs()
This is all in stdio.h.
Example:
#include <stdio.h>
int main(){
FILE *input = fopen("file.txt", "r");
char text[100]; // Where we'll put our text we read
fgets(text, 100, input); // Get up to 100 chars, stops at the first newline
puts(text); // In your example, this should print out "12 1"
fgets(text, 100, input); // Get the next up to 100 chars
puts(text); // Prints "12 3"
return 0;
}
Let me know if there's anything wrong with the code, I don't have a C compiler with me.

Resources