Writing large quantity of integers in a txt file in c - c

I wrote this code where I generate random integers in a large quantity and store them in a txt file. it works if I input up to 49 integers
but after that it does not read any further from the file or the file don't accept any further I don't know please help me
this is the code
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
FILE *fptr;
int num, n;
fptr = fopen("integers.txt", "w");
if (fptr != NULL)
{
printf("File created successfully!\n");
}
else
{
printf("Failed to create the file.\n");
return -1;
}
printf("Enter some integer numbers [Enter -1 to exit]: ");
scanf("%d", &n);
while (n != 0)
{
num = rand();
putw(num, fptr);
n--;
}
fclose(fptr);
fptr = fopen("integers.txt", "r");
printf("\nNumbers:\n");
int count = 0;
while ((num = getw(fptr)) != EOF)
{
printf("%d\n", num);
count++;
}
printf("\nNumber of elements in the file %d",count);
fclose(fptr);
return 0;
}

You have following problems:
As you're writing binary data, the file needs to be opened with "wb" and "rb" (b stands for binary). Othwerwise certain unwanted text substitutions will take place.
If one of your random numbers turns out to be -1, the read will stop prematurely because EOF has the value -1. Therefore you need to do the end of file check with the feof function instead of comparing the value read with EOF.
fptr = fopen("integers.txt", "wb"); // <<< open with binary mode "wb"
...
fptr = fopen("integers.txt", "rb"); // <<< open with binary mode "rb"
printf("\nNumbers:\n");
int count = 0;
while (1)
{
num = getw(fptr);
if (feof(fptr)) // end of file reached => stop the loop
break;
printf("%d\n", num);
count++;
}
BTW:
The documentation of getw concerning the return value is pretty misleading, especially the part "A return value of EOF indicates either an error or end of file" seems wrong to me. getw can read -1 values (0xffffffff) without problems.

Related

Write a program in C that reads up to 100 integers from a file, where the first value from the file is the number of subsequent values in the file

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()).

Why is the file storing binary characters? getw() and putw() were asked to be used in the question

I've used a ".txt" extension while reading and writing the file, also the file mode is corresponding to that of "text" type of file. The program runs fine, but instead of storing an ASCII character in the file, it is storing binary characters. I need some assistance here. Thank you.
int main(void)
{
FILE *fp;
int n2, n1;
printf("ENTER A NUMBER: ");
scanf("%d", &n1);
fp = fopen("hello.txt", "w");
if (fp == NULL)
{
printf("ERROR");
exit(1);
}
fprintf(fp, "%d", n1);
//fclose(fp);
//rewind(fp);
fp = fopen("hello.txt", "r");
if (fp == NULL)
{
printf("ERROR");
exit(1);
}
//n2 = getw(fp);
fscanf(fp, "%d", n1);
printf("%d", n1);
fclose(fp);
}
If you are going to close and reopen the file you don't need rewind. Or you can open the file to read and write, and then you can use rewind. Both work, here is a sample of the latter:
int main(void)
{
FILE *fp;
int n2, n1;
printf("ENTER A NUMBER: ");
if (scanf("%d", &n1) == 1) // checking if the input was correctly parsed
{
fp = fopen("hello.txt", "w+"); // open to read and write
if (fp == NULL)
{
printf("ERROR");
exit(1);
}
putw(n1, fp); // write to the file
rewind(fp); // go back to the beginning of the file
n2 = getw(fp); // get the data
printf("%d", n2);
fclose(fp);
}
else
{
puts("Bad input");
}
}
Live sample
There is still the matter of possible integer overflow when reading from stdin, if there is no requirement to guard against that, make sure to at least document the vulnerability, otherwise the advice is to use fgets to read input and strtol to convert the value.
You should send address of a variable in fscanf, like this:
fscanf(fp,"%d",&n1);

Can't I use fscanf() for infinite time?

#include <stdio.h>
main() {
int n;
FILE *file;
printf("We are here to create a file!\n");
file = fopen("demo.txt", "w+");
if (file != NULL)
printf("Succesfully opened!");
printf("Enter number\n");
while (scanf("%d", &n)) {
fprintf(file, "%d", n);
}
fclose(file);
}
why fscanf() is not working here? Here scanf is working properly but fscanf() is not responding or working here. Can anyone explain what the problem is?
Your code has some problems:
the prototype for main without arguments is int main(void)
you do not exit the program if the file cannot be opened. You will have undefined behavior if fopen returns NULL because you later pass this null pointer to fprintf.
the loop iterates until scanf() returns 0. You should instead iterate while scanf() returns 1. scanf() will return EOF if it fails at end of file, causing an infinite loop.
you should probably output a separator after the number in fprintf() otherwise all numbers are going to be clumped together forming a long sequence of digits.
main() should return 0 or an error status
Here is a corrected version:
#include <stdio.h>
int main(void) {
int n;
FILE *file;
printf("We are here to create a file\n");
file = fopen("demo.txt", "w");
if (file != NULL) {
printf("Successfully opened\n");
} else {
printf("Cannot open demo.txt\n");
return 1;
}
printf("Enter numbers\n");
while (scanf("%d", &n) == 1) {
fprintf(file, "%d\n", n);
}
fclose(file);
return 0;
}
Regarding your question: why can't I use fscanf() instead of scanf()?
you can use fscanf() as long as you give it a stream pointer opened for reading: if you write while (fscanf(stdin, "%d", &n) == 1) the program will behave the same way.
if you want fscanf() to read from file, you need to perform a file positioning command between read and write operations, such as rewind() of fseek(). Yet fscanf() will fail if there is no number to read at the current position in the file and since you open file with "w+" mode, fopen() will be truncated it.
You could cause an infinite loop by writing a number to the file, rewinding it to the beginning and re-reading the same number, etc.
Here is some code for illustration:
#include <stdio.h>
int main(void) {
int n;
FILE *file;
printf("We are here to create a file\n");
file = fopen("demo.txt", "w+");
if (file != NULL) {
printf("Successfully opened\n");
} else {
printf("Cannot open demo.txt\n");
return 1;
}
printf("Enter a number: ");
if (scanf("%d", &n) == 1) {
fprintf(file, "%d\n", n);
rewind(file);
while (fscanf(file, "%d", &n) == 1) {
printf("read %d from the file\n", n);
if (n == 0)
break;
rewind(file);
fprintf(file, "%d\n", n >> 1);
rewind(file);
}
}
fclose(file);
return 0;
}
Interaction:
We are here to create a file
Successfully opened
Enter a number: 10
read 10 from the file
read 5 from the file
read 2 from the file
read 1 from the file
read 0 from the file

Maximum number "C"

i'm a begginer in programming and i have a task. I need to find the maximum number from file in.txt with content: 2,5,4,6,7,10 and then write it to file out.txt. Language C. The problems are:
I'm not very good in programing and in english(so if u will try to explane me something in english i don't think that i'll understand every word)
In the end there should be the max number on da screen, but it shows me the very first number
It's not my first theme here and every time the moderator give a link were i can read some text and find the answer, but look at priblem(1) there are too much text and i cannot tranlate everything in those answers(themes)
So help me please i'm a noob/ I have some code:
#include <conio.h>
#include <stdio.h>
main()
{
int N, max;
FILE *F;
F = fopen("in.txt", "r"); // open file
FILE *G;
G = fopen("out.txt", "w"); // open file
fscanf(F, "%d", &max);
while (feof(F))
{
fscanf(F, "%d", &N);
if (max < N)
max = N;
}
printf("max=%d", max); // show the result on the screen
fprintf(G, "%d", max); // put result into out.txt
fclose(F);
fclose(G);
}
Typo:
while(!feof(F))
^--- missing
feof returns TRUE if you're at the end of the specified file handle. Since you just started reading that file, you're NOT at the end, so feof() will return FALSE, and terminate your loop. You never actually read any further numbers.
Adding the ! makes it into "while NOT at the end of the file, read numbers".
Check to see if fopens succeed. Check if scanf succeed.
scanf will fail at EOF and drop out of loops
#include <stdio.h>
int main ()
{
int N,max;
FILE*F;
F=fopen("in.txt","r"); //open file
if ( F == NULL) { // check if fopen failed
printf ( "could not open in.txt\n");
return 1;
}
FILE*G;
G=fopen("out.txt","w"); //open file
if ( G == NULL) {
fclose ( F);
printf ( "could not open out.txt\n");
return 1;
}
if ( ( fscanf(F,"%d",&max)) == 1) // read an int into max. if success return is 1
{
while( ( fscanf(F,"%d",&N)) == 1) // read an int into N. if success return is 1
{
if(max<N)
{
max=N;
}
}
printf("max=%d",max);//show the result on the screen
fprintf(G,"%d",max); //put result into out.txt
}
fclose(F);
fclose(G);
return 0;
}

reading a dat file and adding numbers to array

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;
}

Resources