I'm having some trouble with C language..
I have one file txt with various lines in the form:
F 65 S 4 1 139.56 3704.26
and my program:
p = fopen("dados.txt", "r");
if ( p == NULL) {
printf("\n\nNao foi possivel abrir o arquivo.\n");
exit(1);
}else{
while ( !feof(p) ){
fscanf(p,"%c %d %c %d %d %f %f",
&sexo,&idade,&estadoCivil,&numFilhos,&freq,&mediaGasto,&mediaSalarial);
printf("%c %d %c %d %d %f %f\n",
sexo,idade,estadoCivil,numFilhos,freq,mediaGasto,mediaSalarial);
}
the return is:
looks bad...
if i change in fscanf: %c to %f
the return is:
looks great, but the variable idade is always 0... :S
wtf i have to do?
You have to add the newline to your scanf call:
fscanf(p,"%c %d %c %d %d %f %f\n",
&sexo,&idade,&estadoCivil,&numFilhos,&freq,&mediaGasto,&mediaSalarial);
Without the newline in scanf, the first line will be correct, but the following line assigns the newline from the input to sexo.
Related
I'm making some tests writing in a file.
Every single value numerical turns negative for no reason and i wont that.
I put for example: codigo : 1 and it always show the number -13312 , or codigo : 2 and the output is : -13312
How can i fix it?
#include <stdio.h>
int main() {
int codigo1[100];
int numero_telefone[100];
int numero_dependentes[100];
char nome[100];
char estado_civil[100];
FILE *fp;
if ((fp = fopen("nomes.txt", "a")) != NULL) {
printf("Indique o seu codigo de funcionario [0-100]: ");
scanf("%d", codigo1);
fprintf(fp, "Codigo funcionario: %d \n", codigo1);
printf("Inroduduza o seu nome: ");
scanf(" %s", nome);
fprintf(fp, "Nome: %s \n", nome);
printf("Insira o seu numero de telefone: ");
scanf("%d", &numero_telefone);
fprintf(fp, "Numero de telefone: %d \n", numero_telefone);
printf("Indique o seu estado civil: ");
scanf(" %s", &estado_civil);
fprintf(fp, "Estado civil: %s \n", estado_civil);
printf("Indique o numero de dependentes: ");
scanf("%d", &numero_dependentes);
fprintf(fp, "Numero dependentes: %d \n", numero_dependentes);
}
fclose(fp);
}
codigo is defined as an array of 100 integers. Which means it's essentially a pointer when passed to another function.
In this statement:
scanf("%d", codigo1);
codigo1[0] gets filled with the typed integer. The other 99 values inside that array are undefined. But codigo1[0] is assigned correctly.
But this statement:
fprintf(fp, "Codigo funcionario: %d \n", codigo1);
Is pushing the address of codigo1 onto the stack and the %d format specifier is used to interpret it as an integer. Also, a stack alignment issue if sizeof(&int) != sizeof(int) which is usually the case on 64-bit platforms. That can cause problems with printf statements using multiple format specifiers with corresponding parameters.
The easy fix is to pass the specific integer value you want to write to file:
fprintf(fp, "Codigo funcionario: %d \n", codigo1[0]);
Similar treatment is needed for your other statements. You should also consider if you really need to use arrays. The following works just as well:
int codigo1 = 0;
...
scanf("%d", &codigo1); // &codigo1 is the "address of" codigo1
fprintf(fp, "Codigo funcionario: %d \n", codigo1);
The code works like a charm at the moment. But, the last 2 lines of output are identical as you can see here.
What is the problem here?
The datas came from a txt file that was build earlier.
1 CADBURY 999 1.900000
2 PEPSI 999 2.500000
3 IPHONE 976 2500.000000
4 SPIRULINA 100 50.000000
2 PAIPSI 100 0.900000
10 BLACKMORE 98 30.000000
17 TROPICANA 13 1.500000
17 TROPICANA 13 1.500000
Here's the code:
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <ctype.h>
int addProduct();
struct product {
int quantity, reorder, i, id;
char name[20];
float price;
};
int main() {
FILE *fp;
int i = 0;
struct product a;
system("cls");
char checker;
int counter;
do {
fp = fopen("addproduct.txt", "a+t");
system("cls");
printf("Enter product ID : ");
scanf(" %d", &a.id);
printf("Enter product name : ");
scanf(" %s", a.name);
printf("Enter product quantity : ");
scanf(" %d", &a.quantity);
printf("Enter product price : ");
scanf(" %f", &a.price);
fprintf(fp, "%d %s %d %f\n\n", a.id, a.name, a.quantity, a.price);
printf("Record saved!\n\n");
fclose(fp);
printf("Do you want to enter new product? Y / N : ");
scanf(" %c", &checker);
checker = toupper(checker);
i++;
system("cls");
} while(checker == 'Y');
if (checker == 'N') {
fp = fopen("addproduct.txt", "r");
while (!feof(fp)) {
fscanf(fp, "%d %s %d %f", &a.id, a.name, &a.quantity, &a.price);
printf("%d %s %d %f\n\n", a.id, a.name, a.quantity, a.price);
}
fclose(fp);
}
return(0);
}
while (!feof(fp)) does not work as expected: feof(fp) only becomes true after input has failed. During the last iteration, fscanf() fails, but you do not check its return value and the values from the previous iterations are used by the last printf().
You should instead write:
while (fscanf(fp, "%d %s %d %f", &a.id, a.name, &a.quantity, &a.price) == 4) {
printf("%d %s %d %f\n\n", a.id, a.name, a.quantity, a.price);
}
When you are printing out the contents of the file at the end of your program, the fscanf function does not set feof until it attempts to read past the end of the file.
This means that after you read the last line in the file, the feof is still not true.
So the loop continues and fscanf then attempts to read another line but fails. So the variables a.id, a.name etc are the same as what they were after the previous loop execution of fscanf.
You should check that fscanf has returned the expected number of fields before you print out the results.
For example,
...
if (fscanf(fp, "%d %s %d %f", &a.id, a.name, &a.quantity, &a.price) == 4)
printf("%d %s %d %f\n\n", a.id, a.name, a.quantity, a.price);
...
would fix the issue.
edit: Sorry 4 parameters not 5, fixed
Hi just getting some weird outputs from trying to read the inputs as double values in C. This issue does not occur when the inputs are integers is there anyway to make it work with double?
#include "stdafx.h"
int main(void)
{
double a, b, c, d, i;
FILE *inp;
inp = fopen("C:\\Users\\student\\Documents\\Visual Studio2012\\Projects\\ConsoleApplication3\\test.txt", "r");
i = fscanf(inp, "%f %f %f %f", &a, &b, &c, &d);
while (i != EOF)
{
printf("a = %f & %d \n", a, i);
printf("b = %f & %d \n", b, i);
printf("c = %f & %d \n", c, i);
printf("d = %f & %d \n", d, i);
printf("%d \n", EOF);
i = fscanf(inp, "%f %f %f %f", &a, &b, &c, &d);
}
fclose(inp);
return 0;
}
Figured it out, the %f in fscanf should be %lf
Change the specifier to %lf in fsacnf and printf statements. Like this -
fscanf(inp,"%lf %lf %lf %lf", &a, &b, &c, &d);
Other problems -
1.Also i is declared as double but in printf you print it with specifier %d ,so you pass wrong argument -
printf("a = %f & %d \n", a, i); // similar in all printf's
So according to me declare i as int and then print it.
2.Also you should always check return of fopen so check it.
So far i have:
char r[4][10];
printf("Enter an option: \n");
scanf("%s %s %s %s %s", r[0],r[1],r[2], r[3], r[4]);
printf("%s %s %s %s %s\n", r[0], r[1], r[2], r[3], r[4]);
This works as long as 5 inputs are given. Right now if you type less then 5 inputs and hit enter the program continues to ask for input until it has all 5 values but I want the scanf to stop and the program to continue if less then 5 inputs are entered.
You'll do best to read a line with fgets() and parse it with sscanf(). If there will be no more than 5 words on a line:
char r[5][10];
char line[4096];
printf("Enter an option: \n");
if (fgets(line, sizeof(line), stdin) != 0)
{
int num = sscanf(line, "%9s %9s %9s %9s %9s", r[0],r[1],r[2], r[3], r[4]);
for (int i = num; i < 5; i++)
r[i][0] = '\0';
printf("%s %s %s %s %s\n", r[0], r[1], r[2], r[3], r[4]);
}
Note that you only had r[4][10] but were using subscript 4 — bad move.
A better way to handle it would be a loop that scans over the line, reading a word at a time until there is no more space in the array or no more words in the line. It's a little trickier, though.
int k;
float regionID;
int t;
char string[100];
float avgTemp,totalTemp;
for(k = 0; k < MAX_STATIONS; k++){
if (fgets(string, sizeof(string), fp) == 0){
break;
}
fscanf(fp,"%d %f %d %d %d %d %d %f %f %f", &stationInfo[k].stationID, &stationInfo[k].temperature, &stationInfo[k].year, &stationInfo[k].month, &stationInfo[k].day, &stationInfo[k].hour, &stationInfo[k].minute, &stationInfo[k].location.latitude, &stationInfo[k].location.longitude, ®ionID);
printf("%d %1.2f %d %d %d %d %d %f %f\n", stationInfo[k].stationID, stationInfo[k].temperature, stationInfo[k].year, stationInfo[k].month, stationInfo[k].day, stationInfo[k].hour, stationInfo[k].minute, stationInfo[k].location.latitude, stationInfo[k].location.longitude);
}
So, my program reads my file almost perfectly, but it will not read the first line of my file. Anyone know what might be causing this problem and how I might be able to fix it?
You are quite intentionally reading and discarding a line here:
if (fgets(string, sizeof(string), fp) == 0) {
I think you meant to use sscanf instead of fscanf, so that you use the data returned to you by fgets.
sscanf(string,"%d %f %d %d %d %d %d %f %f %f", ... );
The reason why your program is "not reading the first line of the file" is because it actually already read the first line when you called
if (fgets(string, sizeof(string), fp) == 0)
The change to fix this is simple:
for(k = 0; k < MAX_STATIONS; k++)
{
if (fscanf(fp,"%d %f %d %d %d %d %d %f %f %f", &stationInfo[k].stationID,
&stationInfo[k].temperature,
&stationInfo[k].year,
&stationInfo[k].month,
&stationInfo[k].day,
&stationInfo[k].hour,
&stationInfo[k].minute,
&stationInfo[k].location.latitude,
&stationInfo[k].location.longitude,
®ionID) > 10)
{
break;
}
printf("%d %1.2f %d %d %d %d %d %f %f\n", stationInfo[k].stationID,
stationInfo[k].temperature,
stationInfo[k].year,
stationInfo[k].month,
stationInfo[k].day,
stationInfo[k].hour,
stationInfo[k].minute,
stationInfo[k].location.latitude,
stationInfo[k].location.longitude);
}
Note the fscanf's return value:
On success, the function returns the number of items of the argument list successfully filled. This count can match the expected number of items or be less (even zero) due to a matching failure, a reading error, or the reach of the end-of-file.
Hope this is what you are looking for!