//ok, thanks for help. i edited the code, passed a pointer and now the it prints the number from particular row, prints the number of that row, and prints the sum off all consiquent numbers. Good so far, but...
What i want do do next, is to assign each of the sums to an array, so i can use for loop to check whether the resulting sum equals to any previous resulting sums. i use tab[n]==result;
unfortunatelly after the while loop is done, all the array elements are empty...thanks//
include
include
int main()
{
int result =0;
read_ints("numbers.txt", &result);
}
void read_ints (const char* file_name, int *result)
{
FILE* file = fopen ("numbers.txt", "r");
int i = 0;
int n=1; //row number//
int tab[n]; //array
if (file == NULL)
{
printf("unable to open file %s", file_name);
}
fscanf (file, "%d", &i);
while (!feof (file))
{
printf ("%d ", i);
*result += i;
tab[n]==result;
printf("row number: %d \n", n);
n++;
printf("\n sum of this number and all numbers before is: %d\n", *result);
fscanf (file, "%d", &i);
}
printf("\nnumber from row number one is ... : %d\n", tab[1]);
fclose (file);
}
Your code is mostly right. You're just calling read_ints incorrectly. You should pass in a pointer to result if you want a value returned.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
void read_ints (const char* file_name, int *result) {
FILE* file = fopen (file_name, "r");
int i = 0;
if (file == NULL) {
printf("unable to open file %s\n", file_name);
return;
}
fscanf (file, "%d", &i);
while (!feof (file))
{
printf ("%d ", i);
*result += i;
printf("\n suma tej liczby ze wszystkimi poprzednimi wynosi: %d\n", *result);
fscanf (file, "%d", &i);
}
fclose (file);
}
int main() {
int result =0;
read_ints("liczby.txt", &result);
}
the following proposed code:
properly checks for errors
properly passes the error text to stderr, including the text reason the system thinks the error occurred.
uses the returned value from fscanf() to control the loop
properly contains a 'prototype' for the sub function
properly uses void inside the parens of main() and the prototype of the sub function that receives no parameters.
consistently indents the code, for readability
cleanly compiles
documents why each header file is included
And now, the proposed code:
#include <stdio.h> // FILE, perror(), fopen(), printf(), fclose()
#include <stdlib.h> // exit(), EXIT_FAILURE
void read_ints ( void );
int main( void )
{
read_ints();
}
void read_ints ()
{
FILE* file = fopen ("liczby.txt", "r");
if( !file )
{
perror( "fopen to read liczby.txt failed" );
exit( EXIT_FAILURE );
}
int i = 0;
int result = 0;
while ( fscanf ( file, "%d", &i) == 1 )
{
printf ("%d ", i);
result=result+i;
printf("\n suma tej liczby ze wszystkimi poprzednimi wynosi: %d\n", result);
}
fclose (file);
}
//ok, the code looks better now, but still, the result values doesnt seem to store in the tab[] array. this is due to lack of a pointer or bad declaration of the array(?).
i intented it to be a dynamic array, so that i dont need to declare the specific size of the array.//
#include <stdio.h>
#include <stdlib.h>
void read_ints(const char* file_name, int *result);
int main()
{
int result =0;
read_ints("numbers.txt", &result);
}
void read_ints (const char* file_name, int *result)
{
FILE* file = fopen ("numbers.txt", "r");
int i = 0;
int n=0; //row number//
int m;
int tab[m]; //array//
if (file == NULL)
{
printf("unable to open file %s", file_name);
}
while ( fscanf (file, "%d", &i) ==1)
{
n++;
printf ("%d\n ", i);
*result += i;
printf("\n we are at row nr. %d sum of this number and all numbers before is: %d\n", n, *result);
tab[n]==*result;
}
printf("\nnumber from row number one is ... : %d\n", tab[1]); //this does not work properly //
fclose (file);
}
Related
I've been working on a program to read data from file into a program and print it:
Here is my code:
#include <stdio.h>
#include <stdlib.h>
int main()
{
char *p;
int e;
float f;
static char a[50];
FILE *fp;
fp = fopen("new_input.txt", "r");
if (fp == NULL)
exit(0);
while (1)
{
p = fgets(a, 50, fp);
if (p == NULL)
break;
printf("%s", a);
printf("\n");
fscanf(fp, "%d", &e);
printf("%d", e);
printf("\n");
fscanf(fp, "%f", &f);
printf("%f", f);
printf("\n");
}
fclose(fp);
return 0;
}
Contents of file new_input.txt are:
Girik
12
19.98
Nikhil
13
90.89
On running on OnlineGdb however I get the following output:
Girik
12
19.980000
12
19.980000
khil
13
90.889999
Can someone explain the problem with my code?
I'm concerned about incomplete name "Nikhil" in output and printing of the value 12 and 19.99 twice.
Link to code:
https://onlinegdb.com/r1ufoP8-d
The problem arises because the last fscanf does not parse the \n, so when the cycle restarts the fgets will parse it and print it, naturally the next fscanf is not able to parse the string ("Nikhil", which was not parsed), because it expects an int, it's downhill from there, as the values are not parsed, what's printed is the old values of e and f from the previous cycle.
If you change your last fscanf so it parses the \n everything works fine:
Live demo
while (1)
{
p = fgets(a, 50, fp);
if (p == NULL)
break;
printf("%s", a);
fscanf(fp, "%d", &e);
printf("%d", e);
printf("\n");
fscanf(fp, "%f\n", &f); //<--here
printf("%.2f", f);//.2f specifier so it prints only 2 decimal places
printf("\n");
}
The pointer is also unnecessary you can use fgets itself as a condition i.e.:
while (fgets(a, sizeof a, fp)) //will read until the end of the file
{
printf("%s", a);
//... same code
}
Anyway, here is a version you can use that will render you the expected result and output, and, I would argue, is better:
Live demo
#include <stdio.h>
#include <stdlib.h>
int main()
{
int e;
float f;
static char a[50];
FILE *fp;
fp = fopen("new_input.txt", "r");
if (fp == NULL){
return EXIT_FAILURE;
}
// will parse until \n or 49 characters max (given the container size)
while (fscanf(fp, " %49[^\n]", a) > 0)
// ^ space - will discard any blank characters
{
printf("%s\n", a);
if(fscanf(fp, "%d", &e) > 0){
printf("%d\n", e);
}
if(fscanf(fp, "%f", &f) > 0){
printf("%.2f\n", f);
}
}
fclose(fp);
return EXIT_SUCCESS;
}
I also added the checks for the fscanf returns which is always a good practise.
Or even:
//...
while (fscanf(fp, " %49[^\n]%d%f", a, &e, &f) == 3)
{
printf("%s\n%d\n%.2f\n", a, e, f);
}
//...
However, the best solution, I believe, is to parse everything with fgets and convert the values with sscanf or strtol/strtof, it's a more robust option. Give it a try.
For "read data from file into a program and print it", you can use e.g. fgets or fscanf. Both uses are included in the following adaption of your example:
#include <stdio.h>
#include <stdlib.h>
int main()
{
char *p;
int e;
float f;
static char a[50];
FILE *fp;
// use fgets
printf("\nVersion with using fgets\n\n");
fp = fopen("new_input.txt", "r");
if (fp == NULL) exit(0);
while(fgets(a, 50, fp)!=NULL)
{
printf("%s", a);
}
fclose(fp);
// use fscanf
printf("\nVersion with using fscanf\n\n");
fp = fopen("new_input.txt", "r");
if (fp == NULL) exit(0);
while(fscanf(fp,"%s\n",a)!=EOF)
{
printf("%s\n", a);
}
fclose(fp);
return 0;
}
COMMENTS:
Size of a[50] needs to be larger than maximum line size.
You can also fscanf for numbers (if you are sure, that it is a number).
Check, if string is integer or float (locale) is a new topic.
Another option: With the assumption that you can rely on the format in "new_input.txt" (to account for the comment of Devolus).
#include <stdio.h>
#include <stdlib.h>
int main()
{
char *p;
int g;
float f;
static char a[50];
FILE *fp;
fp = fopen("new_input.txt", "r");
if (fp == NULL) exit(0);
while(fscanf(fp,"%s\n",a)!=EOF){
printf("%s\n", a);
fscanf(fp,"%d\n",&g);
printf("%d\n", g);
fscanf(fp,"%f\n",&f);
printf("%f\n", f);
}
fclose(fp);
return 0;
}
I have been trying to save register.txt contents to my main file and put it into a struct, it works until I try to print the actual struct. Somehow it doesn't go into it, like it does not save as an array, so the print I have written on the last line prints out what is on the register.txt file but the code does not save its contents as an array/struct in the main file. Any help is appreciated, thank you.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define Anvandarnamn 100
#define Register 10
#define antalval 100
typedef struct {
char Fornamn[Anvandarnamn];
char Efternamn[Anvandarnamn];
int alder;
} agare;
typedef struct {
agare user;
char marke[Anvandarnamn];
char typ[Anvandarnamn];
char reg[6];
} fordon;
void Readfile(fordon bil[]) {
FILE *txt;
txt = fopen("Register.txt", "r");
int i;
for (i = 0; i < Register; i++) {
fscanf(txt, "%s %s %s %s %d %s",
bil[i].marke, bil[i].typ, bil[i].user.Fornamn,
bil[i].user.Efternamn, &bil[i].user.alder, bil[i].reg);
}
fclose(txt);
}
int main() {
fordon bil[Register];
Readfile(bil);
int raknare = 0;
int i = 0;
for (i = 0; i < 10; i++) {
printf("%s\t %s\t %s %s\t %d\t %s \n",
bil[i].marke, bil[i].typ, bil[i].user.Fornamn,
bil[i].user.Efternamn, bil[i].user.alder, bil[i].reg);
}
}
There are many reasons your code could fail: you should add some error testing.
test if fopen() succeeds and report failures with an explicit message that includes the filename.
test for fscanf() failure and report those.
Here is a modified version of ReadFile:
// pass the maximum count of records and return actual count
int Readfile(int count, fordon bil[]) {
FILE *txt;
int i;
txt = fopen("Register.txt", "r");
if (txt == NULL) {
fprintf(stderr, "cannot open Register.txt\n");
return -1;
}
for (i = 0; i < count; i++) {
// tell fscanf the maximum length of each string field
if (fscanf(txt, "%99s %99s %99s %99s %d %5s",
bil[i].marke, bil[i].typ, bil[i].user.Fornamn,
bil[i].user.Efternamn, &bil[i].user.alder, bil[i].reg) != 6) {
fprintf(stderr, "read failed for record %d\n", i + 1);
break;
}
}
fclose(txt);
return i;
}
In file I need to read some inputs:
this is an example:
8 15
[1,1] v=5 s=4#o
[4,2] v=1 s=9#x
typedef struct{
int red2;
int stupac2;
int visina;
int sirina;
char boja[10];
}Tunel;
FILE* fin = fopen("farbanje.txt", "r");
Tunel* tuneli = malloc(sizeof(Tunel)*50);
// if(fin!=0)
fscanf(fin,"%d %d", &r,&s);
printf("%d %d", r,s);
int p=0;
while (fscanf(fin, "[%d,%d]", &tuneli[p].red2, &tuneli[p].stupac2) == 2)
{
p++;
}
for(i=0;i<p;i++)
{
printf("[%d,%d]", tuneli[i].red2, tuneli[i].stupac2);
}
Problem is that it wont read me properly inputs from here: [1,1] v=5 s=4#o
Last line where i use printf shows some random numbers.
Agree it is better to use fgets
But if you want to continue to use your current approach,
#include <stdio.h>
#include <stdlib.h>
typedef struct{
int red2;
int stupac2;
int visina;
int sirina;
char boja[10];
}Tunel;
int main(){
int r, s, i;
FILE*fin=fopen("farbanje.txt", "r");
if(fin==NULL) {
printf("error reading file\n");
return 1;
}
Tunel *tuneli=(Tunel*)malloc(sizeof(Tunel)*50);
fscanf(fin,"%d %d\n", &r,&s);
printf("%d %d", r,s);
int p=0;
while (fscanf(fin, " [%d,%d]%*[^\n]", &tuneli[p].red2, &tuneli[p].stupac2) == 2)
{
p++;
}
fclose(fin);
for(i=0;i<p;i++)
{
printf("[%d,%d]", tuneli[i].red2, tuneli[i].stupac2);
}
}
Last line where i use printf shows some random numbers....
The random numbers you see are because the buffers to print were not properly populated yet.
This example shows how to read the file, using fgets() to read a line buffer, then use sscanf() to parse the first two values from the lines. (read in-code comments for a few other tips.)
int main(void)//minimum signature for main includes 'void'
{
int r = 0;
int s = 0;
char line[80] = {0};//{initializer for arrays}
int p = 0;
Tunel *tuneli = malloc(sizeof(*tuneli)*50);
if(tuneli)//always test return of malloc before using it
{
FILE *fin = fopen(".\\farbanje.txt", "r");
if(fin)//always test return of fopen before using it
{
fgets(line, sizeof(line), fin);
sscanf(line, "%d %d", &r, &s);
while(fgets(line, sizeof(line), fin))
{
sscanf(line, " [%d,%d]", &tuneli[p].red2, &tuneli[p].stupac2);
//note space ^ here to read only visible characters
printf("[%d,%d]\n", tuneli[p].red2, tuneli[p].stupac2);//content is now populated corretly
p++;
}
fclose(fin);//close when finished
}
free(tuneli);//free when done to prevent memory leaks
}
return 0;
}
I have a C program that creates a binary file from a text file.
/*makeBinry.c*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main(int argc, char *argv[]){
char *ptext, *btext="file.bin";
if(argc != 2){
printf("Using default \"text.txt\" file to create mnemonics table\n");
ptext = "text.txt";
}else{
ptext = argv[2];
}
FILE *fp, *fb;
if(!(fp=fopen(ptext, "r"))){
fprintf(stdout, "Error: File %s is not available\n", ptext);
exit(1);
}
if(!(fb = fopen(btext, "wb"))){
fprintf(stdout, "Error: File %s is cannot be opened to write\n", btext);
exit(1);
}
int i, j, k;
char s[8], c, stringed[20];
while(!feof(fp)){
memset(stringed, '\0', sizeof(stringed));
fscanf(fp, "%X %d %c %d %[^\n]s", &i, &j, &c, &k, s);
sprintf(stringed, "%X %d %c %d %[^\n]s", &i, &j, &c, &k, s);
fwrite(stringed, 1, strlen(stringed), fb);
}
fprintf(stdout, "Success: %s file successfully created\n", btext);
fclose(fp);
fclose(fb);
return 0;
}
I have another program that reads the data in the binary file and stores into an array.
/*mainProg.c*/
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
#include<string.h>
typedef struct opStruct{
int hexv, fv, kv;
char str[8], key;
} node;
node* makeTable(char *filename){
FILE *fp;
if(!(fp = fopen(filename, "rb"))){
fprintf(stdout, "Error: Unable to open file %s\n", filename);
exit(1);
}
int hv, fv, kv;
char s[8], c, str[20];
while(!(feof(fp))){
sscanf(fp,"%X %d %c %d %[^\n]s", &hv, &fv, &c, &kv, str);
fprintf(stdout, "%X %d %c %d %s", hv, fv, c, kv, str);
}
fclose(fp);
return NULL;
}
int main(){
int i;
char *filename = "file.bin";
node *t_table = makeTable(filename);
return 0;
}
When I run the mainProg.c the program goes into an infinite loop. I figured it is because fp is never increased. How could I increase the file pointer and still use sscanf to read the binary file in the formatted manner? I'm not allowed to use fread(). Since currently, I'm not creating the table the function makeTable returns NULL.
Also, since the number of lines in the binary file would be unknown, how can I create the array dynamically using realloc?
the following code
properly handles error conditions
actually produces a binary file, rather than just another text file
uses the returned value from fscanf() rather than the faulty feof()
uses perror() so system error message is displayed on stderr
follows the axiom: only one statement per line and (at most) one variable declaration per statement
error checking for the calls to fwrite(), fclose() could be added but they are VERY unlikely to produce an error
and now the code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct record
{
unsigned int hv;
int fv;
int kv;
char c;
char s[8];
};
int main(int argc, char *argv[])
{
char *ptext, *btext="file.bin";
if(argc != 2)
{
printf("Using default \"text.txt\" file to create mnemonics table\n");
ptext = "text.txt";
}
else
{
ptext = argv[1];
}
FILE *fp;
FILE *fb;
if(!(fp=fopen(ptext, "r")))
{
perror( "fopen for read of text file failed" );
fprintf(stdout, "Error: File %s is not available\n", ptext);
exit(1);
}
if(!(fb = fopen(btext, "wb")))
{
perror( "fopen for write of binary file failed" );
fprintf(stdout, "Error: File %s is cannot be opened to write\n", btext);
fclose( fp ); // cleanup
exit(1);
}
struct record myRecord;
// produce binary file from text input
// note: leading space in format string, to consume any left over newline, etc
while(5 == fscanf(fp, " %X %d %c %d %7[^\n]",
&myRecord.hv,
&myRecord.fv,
&myRecord.c,
&myRecord.kv,
myRecord.s) )
{
fwrite( &myRecord, sizeof myRecord, 1, fb );
}
fprintf(stdout, "Success: %s file successfully created\n", btext);
fclose(fp);
fclose(fb);
return 0;
}
/*mainProg.c*/
#include <stdio.h>
#include <stdlib.h>
//#include <malloc.h>
#include <string.h>
//typedef struct opStruct
//{
// int hexv, fv, kv;
// char str[8], key;
//} node;
struct record
{
unsigned int hv;
int fv;
int kv;
char c;
char s[8];
};
//node* makeTable(char *filename)
void makeTable( char *filename )
{
FILE *fp;
if(!(fp = fopen(filename, "rb")))
{
fprintf(stdout, "Error: Unable to open file %s\n", filename);
exit(1);
}
// implied else, fopen successful
struct record myRecord;
// use fscanf() not sscanf()
while( fread( &myRecord, sizeof myRecord, 1, fp) )
{
//sprintf( , "%X %d %c %d %s\n" hv, fv, c, kv, s );
//fprintf(stdout, "%s", str );
fprintf( stdout, "\n%X", myRecord.hv );
fprintf( stdout, " %d", myRecord.fv );
fprintf( stdout, " %c", myRecord.c );
fprintf( stdout, " %d", myRecord.kv );
fprintf( stdout, " %8.8s", myRecord.s );
}
fprintf( stdout, "\n" ); // force flush
fclose(fp);
//return NULL;
} // end function: makeTable
int main( void )
{
//int i;
char *filename = "file.bin";
//node *t_table = makeTable(filename); // raises compiler warning about unused variable
makeTable(filename);
return 0;
} // end function: main
I'm trying to make a program that reads a file with list of names. The number of those names can vary, as well as the names lengths. I want to store them in an array of arrays of char, and read each row as a string to later open the file that corresponds to the name in question. But when I try to open the first one, I have an error opening file.
I'm totally out of ideas.
Help, please?
Here is the code relevant to this action:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
int glimps(char *fname);
int write_av(char *fname, int NumbFiles);
int clr(char *fname);
int readFile(char *fname, int i);
double *dalpha, *alpha, *Ln_t, *LnLnA, Conc;
long *time, *weights, *Lmax, Nmax;
char *av_file, **in_files, *antetka;
/****************************************************************************/
int main(int argc, char *farg[])
{
int i, NumbFiles, flag;
long row;
char *a1;
FILE *fp;
av_file = farg[1];
printf("av_file = %s\n",av_file);
NumbFiles = glimps(av_file);
in_files = (char **) malloc (sizeof(char *) * NumbFiles);
for (i=0 ; i<NumbFiles ; i++)
in_files[i] = (char *) malloc (sizeof(char) * 200);
Lmax = (long *) calloc((size_t) NumbFiles, sizeof(long));
if((in_files == NULL)||(Lmax==NULL)) printf("Грешка при read алок.\n, "), exit(-1);
if (flag = readFile(av_file, -1))
printf("Error in read av_file %s\n", av_file), exit(-1);
weights = (long *) calloc((size_t) Nmax, sizeof(long));
for(i = 0; i<Nmax; i++) weights = 0;
for(i = 0; i<NumbFiles; i++)
{
//if (flag = readFile(&(*in_files[i]), i))
if (flag = readFile(in_files[i], i))
printf("Error in in_files[%d], %s\n",i, &(*in_files[i])), exit(-1);
}
if (flag = write_av(av_file, NumbFiles))
printf("Error in write_av(%s)\n,", av_file), exit(-1);
exit(0);
}
/****************************************************************************/
int glimps(char *fname)
{
FILE *fp;
char buf[140];
int cnt=0;
fp = fopen (fname, "r");
while (fgets(buf,140,fp) )
{
cnt++;
}
fclose(fp);
return (cnt);
}
/****************************************************************************/
int readFile(char *fname, int k)
{
int cnt=0;
FILE *fp;
char buf[200], dummy[13];
printf("fname is %s\n", fname); getchar();
fp = fopen (fname, "r");
if(fp==(NULL)) return(-1);
if(!strcmp(fname,av_file) )
{
while (fgets(in_files[cnt++],200,fp) );
}
else
{
printf("read TUK!\n"); getchar();
fgets(buf,200,fp);
sscanf(buf,"%s %s %s %s %s %s %s %ld %s %s %lf\n",
dummy, dummy,dummy,dummy,dummy,dummy,dummy, &Lmax[k],
dummy, dummy, &Conc);
fgets(buf,200,fp);
sscanf(buf,"%s\n", antetka);
printf("read TUK!\n"); getchar();
while (fgets(buf,200,fp))
{
sscanf(buf,"%ld %lf %lf %s %lf %lf\n",
&time[cnt], &dalpha[cnt], &alpha[cnt], dummy, &Ln_t[cnt],
&LnLnA[cnt]);
weights[cnt++]++;
}
}
fclose(fp);
return (0);
}
...
Console Output:
> ./avr alpha_cubeL.C0.010
av_file = alpha_cubeL.C0.010
fname is alpha_cubeL.C0.010
fname is alpha_cubeL100C0.010
Error in read in_files[0], alpha_cubeL100C0.010
> ls alpha_cubeL100C0.010
alpha_cubeL100C0.010
What happens is that in the readFile function, you read the main file given as argument to make (from the content) several file names in in_files[i], but fgets reads lines including the CR or CRLF (ie the end of line character(s)). Thus later in the program, readFile fails as it tries to open filename + CR [LF].
You may just add a trim function near the top of your program, like
void trim(char *s) {
int i,l = strlen(s);
for (i=l-1 ; i>=0 && (s[i]==10 || s[i]==13) ; i--) s[i] = 0;
}
that removes CR and/or LF that end a string s, and then change the readFile function to trim the file names read in each line, like
while (fgets(in_files[cnt++],200,fp) ) {
trim(in_files[cnt-1]); // cnt-1, or do the cnt++ here (and not above...)
}
Then the files can be opened...
(this is probably not the only problem in this program, but this is a good start)