I am trying to read values from a file and after some operation write to another file. Here facing a slight issue as I am also trying to save values in a 2D Array and displaying it. My file read and file write are showing correct results but my program throws an exception when it comes to display matrix part.
#include <stdio.h>
#include <ctype.h>
#ifndef NULL
#define NULL ((void *) 0)
#endif
int main(void)
{
FILE *file = NULL; //for file read
FILE *fptr = NULL; //for file write
int mat[182][274];
// code to read and display number from file
// open file for reading
file = fopen("file.txt", "r");
fptr = fopen("file1.txt", "w");
int i = 0,j=0;
fscanf (file, "%d", &i);
while (!feof (file))
{
symbol = fgetc(file);
if (symbol == '\n' || feof(file))
{
fprintf (fptr,"\n");
printf("\n");
}
else{
j=255-i;
mat[i][j]=j;
fprintf (fptr,"%d ", j);
fprintf (fptr," ");
printf ("%d ", j);
}
fscanf (file, "%d", &i);
}
fclose (file);
fclose (fptr);
//Facing issue in this part
int k;
int l;
for (k=0;k<=182;k++)
{
for(l=0;l<=274;l++)
{
printf("%d ", mat[k][l]);
}
}
return 0;
}
Arrays in C start at 0 and end at (array_size - 1).
As you're accessing memory just outside the array, you're most likely experiencing segmentation faults.
To fix this issue, change these lines:
for (k=0;k<182;k++)
{
for(l=0;l<274;l++)
{
printf("%d ", mat[k][l]);
}
}
Notice that I changed the relational operators from <= and >= to < and >, respectively.
Along with that, you may need to fully initialize your array. Odd values may be printed if the array is not initialized. (#Weather Vane).
However, to best be sure if this is the case, we need file.txt and file1.txt.
Related
Write code that reads a number of values, interpreted as integers, from a file named “mtData.txt”, where the first number tells how many subsequent numbers there are, and there will never be more than 100 integers.
I'm new to C, coming from a background in Java. I wrote the following, producing an infinite loop that prints the obvious statements and an address not the values from the file.
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
int main(){
FILE *fp = (FILE*) 0;
int c = -1;
fp = fopen("myInput.txt", "r");
if(fp == NULL){
puts("Error accessing file");
return(-1);
}
bool doneReading = false;
int numbers[100];
while (!doneReading){
puts("Reading now");
c = fscanf(fp, "%d", numbers);
printf("Read %d items\n", c);
if(feof(fp)){
doneReading = true;
}
printf("%d\n", numbers);
fclose(fp);
}
}
A possible approach (take a look at how the loop is implemented):
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
int main(void) {
FILE* fp = fopen("myInput.txt", "r");
if (fp == NULL) {
puts("Error accessing file");
return 1;
}
// this is the array that will contain the numbers
int numbers[100];
// this is the number of integers that the file contains
int max_numbers;
// this is the number of integers that we have actually read from the file
int counter = 0;
// max_numbers is actually the first integer that we find in the file
if (fscanf(fp, "%d", &max_numbers) != 1 || max_numbers < 0 || max_numbers > 100) {
printf("ERROR\n");
return 1;
}
printf("Max numbers: %d\n", max_numbers);
// now that we know the number of integers, we can loop to read them all
while (counter < max_numbers) {
if (fscanf(fp, "%d", &numbers[counter]) != 1) {
printf("ERROR\n");
return 1;
}
counter += 1;
}
// now we print all the numbers that we have read
for (int i = 0; i < counter; i += 1) {
printf("Number #%d = %d\n", i, numbers[i]);
}
fclose(fp);
return 0;
}
I used fscanf(fp, "%d", &var) != 1 to put the number inside var and check that everything went well (fscanf() will return the number of arguments successfully assigned, in this case only %d).
EDIT:
The previous code does not check if the file contains more data than necessary (that would also mean that the file is not valid), so it just ignores that extra data (thanks #chux for pointing it out).
Also note that fscanf() will not detect integer overflows, so in the future you may want to look at alternative approaches for integer parsing (e.g.: strtol()).
Absolutely new to C. I am trying to write a program to either read integers contained in a file (passed as arg) or from stdin. First number read is supposed to indicate the array size.
I have something but it throws segmentation fault. Please help.
#include<stdio.h>
#include<stdlib.h>
int main(int argc, char* argv[]) {
FILE *f;
int n, numbers[n], firstNum;
if (argc != 0)
{
f = fopen(argv[1], "r");
fscanf(f, "%d", & firstNum);
int numbersArray[firstNum];
for (int i = 0; i < firstNum; i++)
{
fscanf(f, "%d", &numbersArray[i]);
}
for (int i = firstNum; 0 <= i; i--)
{
printf("Numbers: %d\n\n", numbersArray[i]);
}
fclose(f);
}
else
scanf("%d", &n);
for (int i = 0; i < n; i++)
{
fscanf(stdin, "%d", &numbers[i]);
printf("%d\n", i, numbers[i]);
}
return 0;
}
First off always initialize your variables like kaylum and myself mentioned in the comments.
Unlike some other programming languages C doesn't initialize your variables for you.
Now for the question you posted, you got the idea mostly correct but there are things that i suggest you change:
int n, numbers[n], firstNum;
to
int n = 0, numbers[1000], firstNum = 0;
If you're not happy with that you could move the numbers[n] lower when n is initialized but i wouldn't advise that.
Instead of that, since you're learning C have a look at dynamically allocated arrays using pointers.
Some links to help you understand pointers:
https://www.cprogramming.com/tutorial/c/lesson6.html
https://www.tutorialspoint.com/cprogramming/c_pointers.htm
Next have a look at your fopen it has a return value that tells you if it succeeded to open the file you requested.
So you can add:
f = fopen(argv[1], "r");
if (f == NULL)
{
printf("File Not Found!");
return -1;
}
Modify the condition to suite the way you want to handle that error.
When you're reading the file the user specifies the size of the array you're reading but you should consider the fact that the file may not contain the exact amount of elements.
The function that you are using fscanf has a way to tell you that and that's it's return value.
It will return EOF which is a special value that translates to End Of File.
Consider modifying your fscanf to this:
if (fscanf(f, "%d", &firstNum) == EOF)
{
printf("ERROR");
}
Or if you're in a for loop put break
The last thing is that you don't have to explicitly use fscanf for stdin, the user has specified that he will input it through stdin so you can just as well use scanf.
Hope this helps and good luck with your future C endeavors.
I need to read in a file that contains text, and then a double for that text. It is simply to get the mean and standard deviation for the set of numbers, so the text that comes before is irrelevant. For example, my input file looks a little like:
preface 7.0000
chapter_1 9.0000
chapter_2 12.0000
chapter_3 10.0000
etc..
In this case, it is finding the mean and std dev for the chapters of a book. I have the section of code below, but I'm not quite sure how to "ignore" the text, and only grab the doubles. At the moment this code prints out zeros and only exits the loop when it exceeds the array limit, which I set as a constant to 20 at the beginning of the program.
FILE *ifp;
char *mode = "r";
ifp = fopen("table.txt", mode);
double values[array_limit];
int i;
double sample;
if (ifp==NULL)
{
printf("cannot read file \n");
}
else
{
i = 0;
do
{
fscanf(ifp, "%lf", &sample);
if (!feof(ifp))
{
values[i] = sample;
printf("%.4lf \n", values[i]);
i++;
if (i>=array_limit) //prevents program from trying read past array size limit//
{
printf("No more space\n");
break;
}
}
else
{
printf("read complete\n");
printf("lines = %d\n", i);
}
}while (!feof(ifp));
fclose(ifp);
}
I think you could use fscanf(ifp, "%*[^ ] %lf", &sample) for reading from your file. The * says to ignore that particular match, the [] specifices a list of characters to match and the ^ indicates to match all characters except those in [].
Or possibly (a bit simpler) fscanf(ifp, "%*s %lf", &sample).
You have two major problems -- you're using feof which is pretty much always wrong, and you're not checking the return value of fscanf, which it what tells you whether you got a value or not (or whether you got to the eof).
So what you want is something like
while ((found = fscanf(ifp, "%lf", &values[i])) != EOF) { /* loop until eof */
if (found) {
/* got a value, so count it */
if (++i >= ARRAY_LIMIT) {
printf("no more space\n");
break;
}
} else {
/* something other than a value on input, so skip over it */
fscanf(ifp, "%*c%*[^-+.0-9]");
}
}
When reading in from a file, it's often best to use fgets to read one line at a time, then extract the parts you are interested in using sscanf:
#include <stdlib.h>
#include <stdio.h>
#define ARRAY_LIMIT 10
#define LINE_LENGTH 128
int main()
{
double values[ARRAY_LIMIT];
int i, count = 0;
double sample;
FILE *ifp = fopen("table.txt", "r");
if (ifp==NULL)
{
printf("cannot read file \n");
return 1;
}
char buff[LINE_LENGTH];
while (fgets(buff, LINE_LENGTH, ifp) != NULL)
{
if (sscanf(buff, "%*s %lf", &sample) != 1) break;
values[count++] = sample;
if (count == ARRAY_LIMIT) {
printf("No more space\n");
break;
}
}
fclose(ifp);
for (i = 0; i < count; ++i) {
printf("%d: %f\n", i, values[i]);
}
return 0;
}
fgets returns NULL if it encounters the end of the file, or if a read error has occurred. Otherwise, it reads one line of the file into the character buffer buff.
The asterisk %*s in the sscanf means that the first part of the line is discarded. The second part is written to the variable sample. I am checking the return value of sscanf, which indicates how many values have been read successfully.
The loop breaks when the end of the file is reached or the count reaches the size of the array.
so I have this file called "score.txt" with contents
NAME
20
NAME2
2
And I'm using this code but it gets an error and I have no idea on how to put the integers from the file in an array.
int main(){
FILE* file = fopen ("score.txt", "r");
int i = 0;
fscanf (file, "%d", &i);
while (!feof (file))
{
printf ("%d ", i);
fscanf (file, "%d", &i);
}
fclose (file);
system("pause");
}
I'm only self learning and i've been trying to figure this out for 2hours already
The problem with using fscanf for input where some lines will fail the format is that the file will not be advanced per iteration of the while loop, so you get stuck.
You can get a solution by using fgets to grab the data and sscanf to grab the number:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
int main(void) {
int i = 0;
int ret = 0;
char buf[50];
FILE *file = fopen("score.txt", "r");
if (file == NULL) {
fprintf(stderr,"Unable to open file\n");
exit(1);
}
while (fgets(buf,sizeof(buf),file)) {
ret = sscanf(buf,"%d",&i);
if (ret == 1) { // we expect only one match
printf("%d\n", i);
} else if (errno != 0) {
perror("sscanf:");
break;
}
}
fclose(file)
return(0);
}
This will output, for your input:
20
2
We check the output of sscanf as it tells us if the format has been matched correctly, which will only happen on the lines with integer, and not the 'NAME' lines. We also check for 'errno' which will be set to non-zero if sscanf encounters an error.
We used char buf[50]; to declare a char array with 50 slots, which fgets then uses to store the line its reading; however if the line is more than 50 chars in length it will be read in 50 char chunks by fgets, and you may not get the results you desire.
If you wish to store the integers you read into an array, you'll have to declare an array, then on each read assign a slot in that array to the value of the int you read i.e. int_array[j] = i (where j will have to change with each slot you use). I'll leave it as an exercise to implement this.
My program requires me to read a dat file with a list of numbers. My goal is to get each number and add them to an array. The file has around 100 numbers in this format:
1
2
3
(styling is a bit off sorry ;[ )
so far i have
int main()
{
double prices[1000];
int count,price;
FILE *file;
file = fopen("price.dat","r");
if(file == NULL)
{
printf("Error: can't open file to read\n");
}
else
{
printf("File prices.dat opened successfully to read\n");
}
if (file){
while (fscanf(file, "%d", &price)!= NULL){
count++;
prices[count]=price;
}
}
fclose(file);
}
Problem is that it continues adding the last number continuously. Any help?
You have several problems in your code. To name a few:
fscanf doesn't return a pointer so you shouldn't be comparing it with NULL. All scanf functions returns an integer which can be positive, zero or negative.
You don't initialize count so it will contain a seemingly random value.
Indexing of arrays starts a zero, so you should not increase the array index count until after the assignment.
The actual problem with not wanting to stop is because of the first point.
#include <stdio.h>
#include <string.h>
#define PRICES_LIST_MAX 1000
#define PRICES_FILE "price.dat"
int main()
{
double prices[PRICES_LIST_MAX];
int count = 0;
int i = 0;
FILE *file;
file = fopen(PRICES_FILE,"r");
if(!file)
{
perror("Error opening file");
return -1;
}
memset(prices, 0, sizeof(prices));
while (!feof(file) /* Check for the end of file*/
&&(count < PRICES_LIST_MAX)) /* To avoid memory corruption */
{
fscanf(file, "%lf", &(prices[count++]));
}
fclose(file);
/* Print the list */
printf("Prices count: %d\n", count);
for(i = 0; i < count; i++)
{
printf("Prices[%d] = %lf\n", i, prices[i]);
}
return 0;
}