This is part of a project that i'm doing. Essentially i want to read a text file called "Circuit" that has this inside:
Circuit title example
V1 1 0 24
V2 3 0 15
R1 1 2 10000
R2 2 3 8100
R3 2 0 4700
To give you some context, the values represent a circuit like this:
Circuit example
I made a code to save all these values in a structure and printed them out to see if they were being saved correctly.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct
{
char type, name, noMaior, noMenor;
int value;
}line;
int main(void)
{
line ramo[10];
FILE *ficheiro;
int i = 0, j;
char titulo[200];
if ((ficheiro = fopen("circuit.txt", "r")) == NULL)
printf("Error opening file!");
fgets(titulo, 199, ficheiro);
printf("%s", titulo);
while ((fscanf(ficheiro, "%c%c %c %c %d\n", &ramo[i].type, &ramo[i].name, &ramo[i].noMaior, &ramo[i].noMenor, &ramo[i].value)) != EOF)
{
i++;
//if (fgetc(ficheiro)=='.')
// break;
}
fclose(ficheiro);
for (j = 0; j < i; j++)
printf("%c%c %c %c %d\n", ramo[j].type, ramo[j].name, ramo[j].noMaior, ramo[j].noMenor, ramo[j].value);
return 0;
}
It outputs the same text that is in the file, which is what i intended. Now here comes the tricky part, we have to put ".end" or ".END" in the end of our file, so i made those two commented lines to scan the file for a dot and stop reading it if it encounters one but it causes me some problems when saving the values to the structure. This is what i get as an output:
Circuit title example
V1 1 0 24
2 3 0 15
1 1 2 10000
2 2 3 8100
3 2 0 4700
The "break" works as intended, because if i put a dot in the middle of the file it will stop reading whatever comes after but sadly it is ignoring the first letter and according to the debug tool it is saving a ' ' (a space) in the place of the letters (ramo[].type). I tried to learn as much as i could about the behaviours of fscanf and fgetc but i can't draw any conclusion as to why this is happening.
PS: tried to translate some of the variables to make it easier to read but some are still in portuguese, like "ficheiro"=file. Also take it easy on me folks, i just started learning coding!
Use fgets to read each line from the file. Then you can check for a dot or use strncmp or strcmp to test for specific values. If the value is not detected, parse the line using sscanf.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct
{
char type, name, noMaior, noMenor;
int value;
}line;
int main(void)
{
line ramo[10];
FILE *ficheiro;
int i = 0, j;
char titulo[200];
char input[200];
if ((ficheiro = fopen("circuit.txt", "r")) == NULL)
printf("Error opening file!");
fgets(titulo, sizeof titulo, ficheiro);
printf("%s", titulo);
while ( fgets ( input, sizeof input, ficheiro))
{
if ( '.' == input[0]) {//test for a dot at start of line
break;
}
else {
if (( 5 == sscanf(input, "%c%c %c %c %d"
, &ramo[i].type, &ramo[i].name, &ramo[i].noMaior, &ramo[i].noMenor, &ramo[i].value))) {
i++;
}
}
}
fclose(ficheiro);
for (j = 0; j < i; j++)
printf("%c%c %c %c %d\n", ramo[j].type, ramo[j].name, ramo[j].noMaior, ramo[j].noMenor, ramo[j].value);
return 0;
}
Related
I'm trying to read numbers from a file, but first i gotta skip a header, this is a small code that only serves the purpose of testing the function, now...the function to skip part of the file works fine but when i try and read somthing from the file after i get a seg fault and the error code that means Status_acces_violation, but i just can't seem to find my mistake
The info in the file is always gonne be like this
Ex:
P5
256 789
125
125 236 789 ...(a bunch of numbers)
#include <ctype.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
FILE *salt_header(FILE *poza){
char gunoi1[2];
fscanf(poza, "%s", gunoi1);
printf("%s\n", gunoi1);
int gunoi2;
fscanf(poza, "%d ", &gunoi2);
printf("%d ", gunoi2);
fscanf(poza, "%d", &gunoi2);
printf("%d\n", gunoi2);
fscanf(poza, "%d", &gunoi2);
printf("%d\n", gunoi2);
return poza;
}
int main()
{
FILE *poza;
char gunoi1[2], *nume;
nume = malloc(256 * sizeof(char *));
if(nume == NULL)
exit(-11);
scanf("%s", nume);
poza = fopen(nume, "r");
if(poza == NULL){
printf("Failed to open file\n");
exit(-1);
}
poza = salt_header(poza);
int numar;
for(int i = 0; i < 3; i++){
fscanf(poza, "%d", &numar);
printf("%d ", numar);
}
fclose(poza);
free(nume);
return 0;
}
char gunoi1[5]; // "P5" : 2 bytes , "\n" : 1 byte , "\0" : byte
just can't seem to find my mistake
In *scanf(), do not use "%s" without a width.
fscanf(poza, "%s", gunoi1); overflows char gunoi1[2]; as it is too small to store string "P5" leading to undefined behavior (UB). Remember a string always has a trailing null character, else it is not a string.
Also always check the return value of input functions.
A simple alternative, if the first line length is sane:
char buf[1000];
if (fgets(buf, sizeof buf, poza)) {
; // Successfully read the first line.
}
I'm trying to read txt files and place the information into structs for a C class project. My code doesn't seem to read the file and put the info into struct. I read many blog posts but I can't find or correct my mistakes.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct flightData {
char airline[9];
int flightCode;
char departureAirport[3];
char destinationAirport[3];
int passengerCapacity;
int depTimeHour;
int depTimeMin;
int arvTimeHour;
int arvTimeMin;
};
int main(){
FILE *flightFile;
flightFile = fopen("flights.txt","r");
int flightCount=0;
struct flightData input[10];
if (flightFile == NULL)
{
fprintf(stderr, "\nError opening file\n");
exit (1);
}
while (fscanf(flightFile,"%s %d %s %s %d %d:%d %d:%d", input[flightCount].airline,&input[flightCount].flightCode,input[flightCount].departureAirport,input[flightCount].destinationAirport
,&input[flightCount].passengerCapacity,&input[flightCount].depTimeHour,&input[flightCount].depTimeMin,&input[flightCount].arvTimeHour,&input[flightCount].arvTimeMin)!= EOF){
flightCount++;
printf ("%s\n",input[flightCount].airline);
}
fclose(flightFile);
return 0;
}
And here is the .txt file
THY 12345 IST DUD 10 20:05 16:10
LUFTHANSA 23356 IST MUC 10 11:55 12:40
PEGASUS 34567 SAW MUC 10 12:20 17:00
PEGASUS 45678 SAW XSP 10 01:55 17:20
EMIRATES 67890 ADB HKG 10 19:45 15:50
THY 78901 SAW IST 10 07:20 08:25
From this code I'm getting this result:
X����
P+�
You must never use "%s" in scanf. It is no better than gets. To use %s safely in a scanf you must use a maximum field width in the conversion specifier that is one less than the size of the buffer. scanf will read no more than the number of characters specified, and will write the characters read plus a null terminator. There are a few other (mostly trivial) issues in your code. Try something like:
int
main(int argc, char **argv)
{
const char *path = argc > 1 ? argv[1] : "flights.txt";
FILE *flightFile = fopen(path,"r");
int flightCount=0;
struct flightData input[10], *t = input;
if( flightFile == NULL ) {
perror(path);
return EXIT_FAILURE;
}
char fmt[128];
snprintf(fmt, sizeof fmt, "%%%zus %%d %%%zus %%%zus %%d %%d:%%d %%d:%%d",
sizeof t->airline - 1, sizeof t->departureAirport - 1,
sizeof t->destinationAirport - 1);
while( fscanf(flightFile, fmt, t->airline, &t->flightCode,
t->departureAirport, t->destinationAirport,
&t->passengerCapacity, &t->depTimeHour, &t->depTimeMin,
&t->arvTimeHour, &t->arvTimeMin) == 9 )
{
t += 1;
}
fclose(flightFile);
flightCount = t - input;
for( int i = 0; i < flightCount; i++ ){
printf("%s\n", input[i].airline);
}
return 0;
}
Note that you may want to add some additional diagnostics. Given your current struct definition (in which the strings are too small), this example will enter the body of the while loop zero times and set flightCount to zero, since scanf will not be able to read the first line of input. Handling that is left as an exercise for the reader.
The most severe error apart from the ones mentioned in the question comments is the lines
flightCount++;
printf ("%s\n",input[flightCount].airline);
where the index flightCount is incremented before the input array is accessed, hence an uninitialized value is retrieved. Swap those two lines, do what the above comments recommend, and it will look much better.
i'm trying to read variables from a txt file.
The file .txt is like:
john 10
mark 230
peter 1
I would like to transfer and save this values in an array, for example array[0] = 10, array[1] = 230 etc without minding of names. I pasted my code below and I would like to know how can i edit it using this code below
int conf[4], i = 0, c;
FILE *file_conf;
file_conf = fopen("conf.txt", "r");
if(file_conf == NULL){
fprintf(stderr, "Error\n");
exit(EXIT_FAILURE);
} else {
while((c = fgetc(file_conf)) != EOF) {
fscanf(file_conf, "%d", &conf[i]);
printf("%d\n", conf[i]);
i++;
}
}
You should not be using fgetc() at all--that gets a single character. Instead, add the name format to your fscanf(), something like this:
char name[100];
fscanf(file_conf, "%s %d", name, &conf[i]);
You can prefix scanf() family conversion specifiers with * to suppress assignment. Note that in the posted code, failure to check the value returned from fscanf() could lead to problems with malformed input. Also, the input loop should exit when the array index i grows too large to avoid buffer overflow. The following code exits the loop when i is too large, or when malformed input is encountered:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int conf[4], i = 0;
FILE *file_conf;
file_conf = fopen("conf.txt", "r");
if(file_conf == NULL){
fprintf(stderr, "Error\n");
exit(EXIT_FAILURE);
} else {
while(i < 4 && fscanf(file_conf, "%*s%d", &conf[i]) == 1) {
printf("%d\n", conf[i]);
i++;
}
}
fclose(file_conf);
return 0;
}
Output using using the posted sample input:
10
230
1
#include <stdio.h>
#include <stdlib.h>
//#define true 0
typedef struct
{
char currency[8];
int exchangerate;
} randT;
void main()
{
int i, num;
char currency1[8], ch;
FILE *file = fopen("address", "r");
randT name[7];
while(fscanf(file, "%i", &name[i].exchangerate) != EOF)/*I think this is where my problem is*/
{
fscanf(file, "%s %i", &name[i].currency, &name[i].exchangerate);
//printf("%s %i\n", currency1, num);
//if (fscanf(file, "%i", ¤cy1) == EOF) break;
printf("%s %i\n", name[i].currency, name[i].exchangerate);
i++;
}
fclose(file);
}
It is giving segmentation fault(core dumped) and i am fairly new to the fscanf functions and such. Please help!
my text file looks like this:
jeff 4
jina 5
jeffrey 6
jinna 7
jeffu 8
jinina 9
jeffz 10
The cause of the crash is that you need to initialize int i = 0;. As you have it, i is indeterminate, so probably name[i] is a massively out-of-bounds access.
For the fscanf, you have mostly the right idea about the loop, except instead of checking != EOF it's better to check == 1 or however many items you were reading. If the file contains something that can't be processed as a number, then fscanf will not return EOF.
However this is not the right way to read your particular file. You read %i then %s %i every time around, but your file only contains a string and an int. Change to:
while ( 2 == fscanf(file, "%7s %i", name[i].currency, &name[i].exchangerate) )
Also after doing i++ you need to check that i has not gone out of bounds (i.e. it's less than 7).
Note that name[i].currency decays to pointer to char - you shouldn't put & on it. Also you should use the length specifier to avoid running over the end of the array.
I would use the loop structure:
for (num_read = 0; num_read < sizeof name / sizeof name[0]; ++num_read)
{
if ( 2 != fscanf(file,.....
break;
printf(....
}
my text file format is this:
3.2 , 5.6
444.2 , 555
112.34 , 32.3
i want to read the above information present within file name file.txt and store it in two arrays a,b where a will have the float value before the comma and b will have the float value after the comma
Use fgets() in a loop to read each line. Then once you have the line, use sscanf() to scan out the two floating-point numbers, like so:
while(fgets(line, sizeof line, myfile) != NULL)
{
if(sscanf(line, "%f,%f", &a[i], &b[i]) == 2)
{
++i;
}
else
printf("Parse error in %s", line);
}
Note that the return value from sscanf() says how many conversions that succeeded. If it isn't two, we don't want to move forward in the array. Remember to make sure i is initialized to 0 before the loop, of course.
E.g.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define DATA_SIZE 10
int main (void){
char filename[256] = "file.txt";
char input_line[128];
FILE *fp;
float a[DATA_SIZE], b[DATA_SIZE];
int i,j;
if(NULL==(fp=fopen(filename, "r"))){
perror("input file open");
return -1;
}
i=0;
while(NULL!=fgets(input_line, sizeof(input_line), fp)){
if(*input_line == '\n') continue;
a[i]=atof(strtok(input_line, " ,\n"));//ok even this ","
b[i]=atof(strtok(NULL , " ,\n"));
++i;
}
//check print
for(j=0;j<i;++j){
printf("a[%d]=%g, b[%d]=%g\n", j, a[j], j, b[j]);
}
return 0;
}