Reading from file in C - Wrong output - c

I am writing a code to read from a file but it always prints wrong output.
The code is as follows:
int n;
struct threeNum num = { 0 };
FILE *fptr;
if ((fptr = fopen("input.txt", "rb")) == NULL) {
printf("Error! opening file\n");
// Program exits if the file pointer returns NULL.
exit(1);
}
for (n = 1; n < 5; ++n)
{
fread(&num, sizeof(struct threeNum), 1, fptr);
printf("n1: %d\tn2: %d\tn3: %d\n", num.n1, num.n2, num.n3);
}
fclose(fptr);
The struct is:
struct threeNum
{
char n1, n2, n3;
};
And the .txt file is:
1 2 3
5 6 7
6 6 9
5 5 5
8 7 2
And I always get zeros printed.

fread reads binary objects, but your file is text. You need to read text and then parse that (such as with fscanf, or fgets followed by sscanf).

// As #Arkku said, use fgets to read each line and sscanf to parse it.
#include <stdio.h>
#include <stdlib.h>
int main() {
int num[15];
int totalRead, i = 0;
char dataToRead[50];
FILE *fp;
if ((fp = fopen("file.txt", "r")) == NULL) {
printf("Error! opening file\n");
// Program exits if the file pointer returns NULL.
exit(1);
}
// read the file
while (fgets(dataToRead, 50, fp) != NULL) {
totalRead = sscanf(dataToRead, "%d%d%d", &num[i], &num[i+1], &num[i+2]);
puts(dataToRead);
i = i + 3;
}
// I used modulo so that after every 3rd element there is a newline
for (i = 0; i < 15; i++) {
printf("%d ", num[i]);
if ((i+1) % 3 == 0)
printf("\n");
}
return 0;
}

Related

C safe usage of scanf/freopen/fopen to read from text file into an array

My input is:
5 1 2 3 4 5 6
My expected output is this:
10 2 4 6 8 10 12
Generally, I want to read my input and store it in an array arr, given that I don't know how many numbers I have as an input, so I don't know when the lines ends, I should just keep reading.
I am using C for the first time, and I have tried to write a safe code. Specifically, I wanted to use fopen instead of freopen, I checked for return values of scanf and fopen and instead of while(!feof(filepointer)) I did the one with for(;;) and break. My question is:
I run my code and it gives me an infinite loop, why?
Did I do good readings?
This is the code:
#define MAX 100
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
int main() {
// ....................read data........................
FILE* inp = fopen("input.txt", "r");
FILE* out = fopen("output.txt", "w");
if (inp == NULL) {
fprintf(stderr, "Unable to reopen stdin.\n");
return EXIT_FAILURE;
}
if (out == NULL) {
fclose(inp);
fprintf(stderr, "Unable to reopen stdout.\n");
return EXIT_FAILURE;
}
int a, n = MAX, i = 0;
//int* arr = malloc(sizeof * arr * length);
int* arr = calloc(n, sizeof * arr);
for (;;) {
if (fscanf(inp,"%d", &a) != 1) {
fprintf(stderr, "Failed to read an int.\n");
break;
}
else {
arr[i] = a;
fprintf(stdout, "%d ", arr[i] * 2);
i++;
}
}
// ....................close - free........................
free(arr);
fclose(inp);
fclose(out);
return 0;
}

How to read the content from the second line onwards on a .txt file on C

I need help to read the numbers of a .txt file and put them in an array. But only from the second line onwards. I'm stuck and don't know where to go from the code that i built.
Example of the .txt file:
10 20
45000000
48000000
56000000
#define MAX 50
int main (void){
FILE *file;
int primNum;
int secNum;
int listOfNumers[50];
int numberOfLines = MAX;
int i = 0;
file = fopen("file.txt", "rt");
if (file == NULL)
{
printf("Error\n");
return 1;
}
fscanf(file, "%d %d\n", &primNum, &secNum);
printf("\n1st Number: %d",primNum);
printf("\n2nd Number: %d",secNum);
printf("List of Numbers");
for(i=0;i<numberOfLines;i++){
//Count the number from the second line onwards
}
fclose(file);
return 0;
}
You just need a loop to keep reading ints from file and populate the listOfNumers array until reading an int fails.
Since you don't know how many ints there are in the file, you could also allocate the memory dynamically. Example:
#include <stdio.h>
#include <stdlib.h>
int main(void) {
FILE* file = fopen("file.txt", "rt");
if(file == NULL) {
perror("file.txt");
return 1;
}
int primNum;
int secNum;
if(fscanf(file, "%d %d", &primNum, &secNum) != 2) {
fprintf(stderr, "failed reading primNum and secNum\n");
return 1;
}
unsigned numberOfLines = 0;
// allocate space for one `int`
int* listOfNumers = malloc((numberOfLines + 1) * sizeof *listOfNumers);
// the above could just be:
// int* listOfNumers = malloc(sizeof *listOfNumers);
while(fscanf(file, "%d", listOfNumers + numberOfLines) == 1) {
++numberOfLines;
// increase the allocated space by the sizeof 1 int
int* np = realloc(listOfNumers, (numberOfLines + 1) * sizeof *np);
if(np == NULL) break; // if allocating more space failed, break out
listOfNumers = np; // save the new pointer
}
fclose(file);
puts("List of Numbers:");
for(unsigned i = 0; i < numberOfLines; ++i) {
printf("%d\n", listOfNumers[i]);
}
free(listOfNumers); // free the dynamically allocated space
}
There are a few ways to approach this; if you know the size of the first line, you should be able to use fseek to move the position of the file than use getline to get each line of the file:
int fseek(FILE *stream, long offset, int whence);
The whence parameter can be:
SEEK_SET : the Beginning
SEEK_CUR : the current position
SEEK_END : the End
The other option would to encapsulate the entire file read in a while loop:
char *line = NULL;
size_t linecap = 0;
ssize_t linelen;
int counter = 0;
while((linelen = getline(&line, &linecap, file)) != -1){
if counter == 0{
sscanf(line, "%d %d\n", &primNum, &secNum);
}else{
//Process your line
}
counter++; //This would give you your total line length
}

C programming: Read lines of numbers from a file and store it in an array

I'm kinda new to programming so sorry for a stupid question. I've been tasked to read first two lines (numbers) and store them as variable n, and the other one in m. Other numbers bellow those two lines need to be read and store it in a dynamic array (malloc to be exact). Each line has exactly one number. I'm having trouble trying to accomplish this.
Here's my code so far:
#include <stdio.h>
#define MAX_LINE 5
int main() {
FILE* in;
FILE* out;
int n, m, list = (int*)malloc(9 * sizeof(int));
in = fopen("ulazna.txt", "r");
out = fopen("izlazna.txt","w");
if ((in && out) == NULL)
{
printf("Error opening the file...");
return -1;
}
while (fscanf(in, "%d\n", &m) != EOF)
{
fscanf(in, "%d\n", &n);
fscanf(in, "%d\n", &m);
printf("First two: %d %d", n, m);
}
//free(list);
fclose(in);
fclose(out);
return 0;
}
File ulazna.txt has:
3
3
This works as intended but when I write:
3
3
1
2
3
4
5
6
7
8
9
My program prints random numbers from this file.
So, I need to read 3 and 3 into n and m. Then, from 1 to 9 into the array list.
Thanks for help in advance :)
Dynamic array size
If you want to dynamically allocate memory for the list, you would have to count the number of lines in the file first.
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int n, m;
/* open the file for reading text using "r" */
FILE *file_in = fopen("ulazna.txt", "r");
if (!file_in) { /* same as `file_in == NULL` */
printf("Failed to open file\n");
return EXIT_FAILURE;
}
int lines = 0; /* number of lines */
int c; /* return value of `fgetc` is of type `int` */
/* go through each character in the file */
while ((c = fgetc(file_in)) != EOF) {
/* increment the number of lines after every line break */
if(c == '\n')
++lines;
}
/* reset pointer to start of file */
rewind(file_in);
/* check the return value of `fscanf` */
if (fscanf(file_in, "%d\n", &n) != 1 ||
fscanf(file_in, "%d\n", &m) != 1) {
printf("File contains invalid line\n");
return EXIT_FAILURE;
}
printf("First two: %d %d\n", n, m);
/* no need to cast `malloc`, because it returns `void *` */
int *list = malloc(lines * sizeof(int));
for (int i = 0; i < lines - 2; ++i) {
/* check the return value of `fscanf` */
if (fscanf(file_in, "%d\n", &list[i]) != 1) {
printf("File contains invalid line\n");
return EXIT_FAILURE;
}
printf("%d\n", list[i]);
}
free(list); /* always free memory allocated by malloc */
fclose(file_in);
return EXIT_SUCCESS;
}
Fixed array size
If you already know that the number of lines in the file is going to be 11, the array has a length of 9 and there is no need to dynamically allocate memory. But because your assignment requires it, I have implemented malloc.
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int n, m;
/* open the file for reading text using "r" */
FILE *file_in = fopen("ulazna.txt", "r");
if (!file_in) { /* same as `file_in == NULL` */
printf("Failed to open file\n");
return EXIT_FAILURE;
}
/* check the return value of `fscanf` */
if (fscanf(file_in, "%d\n", &n) != 1 ||
fscanf(file_in, "%d\n", &m) != 1) {
printf("File contains invalid line\n");
return EXIT_FAILURE;
}
printf("First two: %d %d\n", n, m);
/* the array has a fixed size of 9 */
const int size = 9;
int *list = malloc(size * sizeof(int));
/*
* If you do not have to use malloc, remove the
* above line and uncomment the following line:
*
* int list[size];
*/
for (int i = 0; i < size; ++i) {
/* check the return value of `fscanf` */
if (fscanf(file_in, "%d\n", &list[i]) != 1) {
printf("File contains invalid line or has to few lines\n");
return EXIT_FAILURE;
}
printf("%d\n", list[i]);
}
fclose(file_in);
return EXIT_SUCCESS;
}

Why does this code give warning: format '%s' expects type 'char *' but argument 2 has type 'char(*)[11]'?

#include <stdio.h>
#include <stdlib.h>
#define RIG 5
#define COL 11
int main()
{
FILE *fp;
fp=fopen("swamp.txt","r");
if((fp=fopen("swamp.txt","r"))==NULL)
{
puts("ERROR!");
return -1;
}
char *swamp[RIG][COL];
while(fscanf(fp,"%s",swamp)!=EOF)
{
printf("%s\n",swamp);
}
fclose(fp);
return 0;
}
I'm working with files and I'm getting 2 warnings for the fscanf inside the while. Can somebody explain to me why?
For test.txt as below:
aaaaaaa bbbbbbb ccccccc
ddddddd eeeeeee fffffff
ggggggg hhhhhhh iiiiiii
jjjjjjj kkkkkkk lllllll
you can obtain data with this code (it can process words up to 8 characters in 4 rows and 3 columns):
#include <stdlib.h>
#include <stdio.h>
int main(void)
{
enum {
ROWS = 4,
COLS = 3
};
FILE *fp;
char test[ROWS][COLS][9];
int counter = ROWS * COLS;
if ((fp = fopen("test.txt", "r")) == NULL) {
perror("fopen()");
return EXIT_FAILURE;
}
for (int i = 0; i < ROWS * COLS; i++) {
if (fscanf(fp, "%8s", test[i / COLS][i % COLS]) == EOF) {
counter = i;
break;
}
}
fclose(fp);
for (int i = 0; i < counter; i++) {
printf("%s ", test[i / COLS][i % COLS]);
if ((i + 1) % COLS == 0) {
printf("\n");
}
}
return EXIT_SUCCESS;
}
Let's assume swamp.txt contains:
marsh
bog
quagmire
morass
fen
and that you want to read these lines into the array swamp in your program. Then you might revise your code along these lines. Notice that this avoids opening the file twice, amongst other cleanup operations.
#include <stdio.h>
#define RIG 5
#define COL 11
int main(void)
{
const char filename[] = "swamp.txt";
FILE *fp = fopen(filename, "r");
if (fp == NULL)
{
fprintf(stderr, "failed to open file '%s' for reading\n", filename);
return -1;
}
char swamp[RIG][COL];
int i = 0;
while (i < RIG && fscanf(fp, "%10s", swamp[i]) == 1)
i++;
fclose(fp);
for (int j = 0; j < i; j++)
printf("%d: %s\n", j, swamp[j]);
return 0;
}
The output is:
0: marsh
1: bog
2: quagmire
3: morass
4: fen
Note that the code protects against overflow from a long file by counting words as they're read. You already checked fopen() — that was good. I improved the error message, though. In my opinion, you should never call fopen() with a literal string for the file name because when you report an error on opening the file, you need the file name in the error message, so you'd have to repeat yourself. I fixed the type of the array so it is a 2D array of char and not a 2D array of (uninitialized) char pointers. I arranged to pass each row of the array to fscanf() in turn. I limited the length of the input for each word to prevent overflows there, too.

Read numbers from txt file second line in a C Array

I do have a txt file which looks like this
10
41 220 166 29 151 47 170 60 234 49
How can I read only the numbers from the second row into an array in C?
int nr_of_values = 0;
int* myArray = 0;
FILE *file;
file = fopen("hist.txt", "r+");
if (file == NULL)
{
printf("ERROR Opening File!");
exit(1);
}
else {
fscanf(file, "%d", &nr_of_values);
myArray = new int[nr_of_values];
// push values from second row to this array
}
How can I read only the numbers from the second row into an array in C?
Ignore the first line by reading and discarding it.
You could use something like that:
#include <stddef.h>
#include <stdlib.h>
#include <stdio.h>
int main(void)
{
char const *filename = "test.txt";
FILE *input_file = fopen(filename, "r");
if (!input_file) {
fprintf(stderr, "Couldn't open \"%s\" for reading :(\n\n", filename);
return EXIT_FAILURE;
}
int ch; // ignore first line:
while ((ch = fgetc(input_file)) != EOF && ch != '\n');
int value;
int *numbers = NULL;
size_t num_numbers = 0;
while (fscanf(input_file, "%d", &value) == 1) {
int *new_numbers = realloc(numbers, (num_numbers + 1) * sizeof(*new_numbers));
if (!new_numbers) {
fputs("Out of memory :(\n\n", stderr);
free(numbers);
return EXIT_FAILURE;
}
numbers = new_numbers;
numbers[num_numbers++] = value;
}
fclose(input_file);
for (size_t i = 0; i < num_numbers; ++i)
printf("%d ", numbers[i]);
putchar('\n');
free(numbers);
}

Resources