How do I write and read files on one program? - c

I'd like to write two multiplication tables in a txt file on one program, read the written file, and print it out on the screen.
C2374 error occurs in my code.
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main(void)
{
//File Write
FILE* fp = fopen("99.txt", "wt");
if (fp == NULL)
{
puts("file open fail.");
return 1;
}
int i = 2;
int j;
for (j = 1; j <= 9; j++)
{
fprintf(fp, "\t %d X %d = %2d \n", i, j, i * j);
}
//File Read
char str[100];
FILE* fp = fopen("99.txt", "rt");
while (fgets(str, sizeof(str), fp) != NULL)
printf(str);
fclose(fp);
return 0;
}
How can I get the 'desired output'?
desired output
I'd really appreciate your help.

You cannot declare FILE *fp twice. Minimized scope of variables. Changed loop condition from j <= 9 to j < 10 which how it's usually done. Use freopen() to change the mode of the file handle:
#include <stdio.h>
int main(void) {
FILE* fp = fopen("99.txt", "wt");
if(!fp) {
puts("file open fail.");
return 1;
}
for (int i = 2, j = 1; j < 10; j++)
fprintf(fp, "\t %d X %d = %2d \n", i, j, i * j);
fp = freopen(NULL, "r", fp);
if(!fp) {
puts("file reopen fail.");
return 1;
}
char str[100];
while (fgets(str, sizeof(str), fp) != NULL)
printf(str);
fclose(fp);
}
and expected output:
2 X 1 = 2
2 X 2 = 4
2 X 3 = 6
2 X 4 = 8
2 X 5 = 10
2 X 6 = 12
2 X 7 = 14
2 X 8 = 16
2 X 9 = 18

Related

increment variable doubles at the end of my program

So I have this program where it asks the user for a filename to read, and a filename to save the output to. This program basically counts the frequency of a letter inside the txt file. Here is the program...
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
int main(void)
{
char letter[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ", FileName[50], SaveFile[50], print[256], stry[50], scount[50], point;
int i, j, count = 0;
FILE * readFile, *saveFile;
printf("Enter a file to read: ");
gets(FileName);
printf("Enter a filename to save results: ");
gets(SaveFile);
printf("Letter Frequency\n\n");
saveFile = fopen(SaveFile, "wb");
for(i = 0; i <= strlen(letter)-1; i++)
{
readFile = fopen(FileName, "r");
while(!feof(readFile))
{
fgets(print, 256, readFile);
for(j = 0; j <= strlen(print); j++)
{
if(toupper(print[j]) == toupper(letter[i]))
{
count++;
}
}
point = letter[i];
stry[0] = point;
sprintf(scount, "%d", count);
if(feof(readFile) && count > 0)
{
printf("%s %d\n", stry, count);
fprintf(saveFile, stry);
fprintf(saveFile, " ");
fprintf(saveFile, scount);
fprintf(saveFile, "\n");
}
}
count = 0;
}
fclose(readFile);
return 0;
}
I input a txt file named readme.txt that I modified. It contains
aaa
bbb
ccc
ddd
But when I run it, and used readme.txt to be read, the output is
A 3
B 3
C 3
D 6
The frequency of letter D must be only 3. I further modified the content of the readme.txt file, and figured out that value of the variable count is doubled when reading the last line. For example, the content of the txt file is
hello mama
hihihi
maria maria
woohoo
the output will be
A 6
E 1
H 6
I 5
L 2
M 4
O 9
R 2
W 2
I read my program so many times already, and I still can't find my wrong doings. I hope you can help me fix this problem. Your help will be very much appreciated!
EDIT:
This is what my code looks like after making the changes that were recommended in the comments section:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
int main(void)
{
char letter[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ", FileName[50], SaveFile[50], print[256], stry[50], scount[50], point;
int i, j, count = 0;
FILE * readFile, *saveFile;
printf("Enter a file to read: ");
gets(FileName);
printf("Enter a filename to save results: ");
gets(SaveFile);
printf("Letter Frequency\n\n");
saveFile = fopen(SaveFile, "wb");
for(i = 0; i < strlen(letter); i++){
readFile = fopen(FileName, "r");
while(fgets(print, 256, readFile) != NULL)
{
fgets(print, 256, readFile);
for(j = 0; j <= strlen(print); j++)
{
if(toupper(print[j]) == toupper(letter[i]))
{
count++;
}
}
point = letter[i];
stry[0] = point;
sprintf(scount, "%d", count);
if(feof(readFile) && count > 0)
{
printf("%s %d\n", stry, count);
fprintf(saveFile, stry);
fprintf(saveFile, " ");
fprintf(saveFile, scount);
fprintf(saveFile, "\n");
}
}
count = 0;
}
fclose(readFile);
return 0;
}

C - read TXT change from dup to fgets and sscanf

I read from txt pairs of numbers
How check it only 2 numbers in each line and not 3. I want show the line is the problem for example the pairs file:
3
25 35
14 42
30 60 70
Console: illegal input at line 4
I know That's not the correct way at all. Need use fgets to read and sscanf to parse.
I tried but the memory full garbage. How can I change it correctly?
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
int i, c;
FILE *fp;
char str[100];
fp = fopen("./pairs.txt", "r");
if (dup2(fileno(fp), STDIN_FILENO < 0))
{
printf("Error opening file");
return -1;
}
if (feof(fp))
printf("Error reading file");
scanf("%d", &numOfPairs);
arrNum = (int *)malloc(sizeof(int) * numOfPairs * numbersInPair);
for (int i = 0; i < numOfPairs * numbersInPair; i += 2)
{
int num1, num2;
scanf("%d %d", &num1, &num2);
arrNum[i] = num1;
arrNum[i + 1] = num2;
}
}
Another try NOT working:
int main(int argc, char *argv[])
{
int index, i, numOfPairs;
int c;
FILE *file;
file = fopen("./pairs.txt", "r");
if ((c = getc(file)) == EOF)
{
perror("Error opening file"); //or return 1;
fclose(file);
}
while ((c = getc(file)) != EOF)
putchar(c);
{
fscanf(file, "%d", &numOfPairs);
allNumbers = (int *)malloc(sizeof(int) * numOfPairs * numbersInPair); //need multiply in 2 numbers for each pair
while (!feof(file) && numOfPairs > 0)
{
int x, y, arrIndex = 0;
numOfPairs--;
fscanf(file, "%d %d", &x, &y);
allNumbers[arrIndex] = x;
printf("The X : %d\n", x);
allNumbers[arrIndex + 1] = y;
printf("THE Y : %d\n", y);
arrIndex + 2;
}
fclose(file);
}

Question about writing and reading a 2D integer array to a text file

I would like to do two Things in my code
1)Write a program to write a two dimensional integer array to a text file.
and
2)Write a second program to read a two dimensional integer array from a text file. The second program should print the matrix on screen. Also to get the filename I should use command line argument.
For example on the cmd the output should be like this:
matrix.txt
8 3 3 1
13 5 31 -8
9 9 0 42
And this is the code which I have made. However only the error message "Can't open matrix.txt" comes out. What is the problem with my code?
#include <stdio.h>
#include <stdlib.h>
#define _CRT_SECURE_NO_WARNINGS
#define ROW 3
#define COL 4
#define FILE_NAME "matrix.txt"
void input_matrix(int matrix[ROW][COL], FILE*);
int main()
{
int Multiarray[ROW][COL];
int i, j;
FILE* fp;
fp = fopen_s(&fp, FILE_NAME, "r");
if (fp == NULL)
{
fprintf(stderr, "Can't open %s\n", FILE_NAME);
exit(EXIT_FAILURE);
}
else
{
input_matrix(Multiarray, fp);
for (i = 0; i < ROW; i++)
{
for (j = 0; j < COL; j++)
{
fprintf(fp, "%d ", Multiarray[i][j]);
}
fprintf(fp, "\n");
}
}
//This part should print out the result of my input
close(fp);
return 0;
}
void input_matrix(int matrix[ROW][COL], FILE* fp)
{
int i, j;
fp = fopen_s(&fp, FILE_NAME, "w");
for (i = 0; i < ROW; i++)
{
for (j = 0; j < COL; j++)
{
fscanf_s(fp, "%d", &matrix[i][j]);
// I have already scanned all the element of my array
}
}
}
Function fopen_s returns 0 on success. As result the program fails on success.
Try:
int ret = fopen_s(&fp, FILE_NAME, "r");
if (ret != 0)
{
fprintf(stderr, "Can't open %s\n", FILE_NAME);
exit(EXIT_FAILURE);
}

I am encountering a segmentation fault in my c code

I am trying to update a 2d array generation by generation.
In order to do this, I need to take two arguments: generation number and the initial input txt that contains a 2d array.
But no matter what I wrote, there are always segmentation fault in my code.
I am trying to read a 2d array from the input file.
The file should look similar to this:
1 1 1 0 0
0 0 0 0 0......
int main(int argc, char *argv[]) {
// take arguments//
char* generation;
char* filename;
if (argc < 2)
{
printf("Error\n");
exit(1);
}
else{
generation = argv[1];
filename = argv[2];
}
// read file as a 5*5 matrix//
FILE *file;
file = fopen (filename,"r");
//5*5 matrix//
int gen = atoi(generation);
int cell[5][5];
int i=0;
int j=0;
for (i=0;i<5;i++){
for (j=0;j<5;j++){
fscanf (file, "%d",&cell[i][j]);
}
}
fclose(file);
Thank you so much!!!
In your code you're not using the variable generation but I suppose it should be used to store the matrix dimension. If it is the case in total you're reading 3 arguments so argc should be 3.
If you are reading a file formatted like this:
1 2 3 4 5
6 7 8 9 10
1 1 3 4 5
6 7 8 9 0
The arguments passed at the console are: ./a.out dimension matrix. A simple but unsafe code (it doesn't check the dimension input by the user) is the following:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
FILE *fp;
char *filename;
char *generation;
if (argc < 3)
{
printf("Error\n");
exit(1);
}
else {
generation = argv[1];
filename = argv[2];
fp = fopen(filename, "r");
if (fp == NULL) {
fprintf(stderr, "Error: Cannot open file %s for reading\n", filename);
exit(1);
}
}
int dim = atoi(generation);
int i, j, cell[dim][dim];
for (i = 0; i < dim; i++) {
for (j = 0; j < dim; j++) {
if (fscanf(fp, "%d ", &cell[i][j]) != 1) {
fprintf(stderr, "invalid input for cell[%d][%d]\n", i, j);
fclose(fp);
exit(1);
}
}
}
fclose(fp);
/*Print the matrix */
for (i = 0; i < dim ; i++)
{
for (j = 0; j < dim ; j++)
{
printf("%d ", cell[i][j]);
}
printf("\n");
}
printf("\n");
return 0;
}

Reading numbers from text and order the numbers

Complete task:
Write a program that reads from a text file 10 integer numbers. The
file has to be previously created using a different code or by using
the operating system’s facilities. Write the functions that:
- order the integers array in ascending/descending order and displays the result
- count the number of even numbers in the array and display the result
My code:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <conio.h>
#include <string>
void cresc(int citire[20]);
FILE *fpointer;
void main()
{
char fisier[12];
int i,citire[20];
printf("Dati un nume fisierului:");
scanf("%s", &fisier);
strcat(fisier, ".txt");
fpointer = fopen(fisier, "w");
fprintf(fpointer, "9865742031");
fclose(fpointer);
fpointer = fopen(fisier, "r");
for (i = 0;i < 9;i++)
fscanf(fpointer, "%d", &citire[i]);
fclose(fpointer);
fpointer = fopen(fisier, "a+");
fprintf(fpointer,"\nNumerele puse in ordine sunt: \n");
cresc(citire);
fclose(fpointer);
_getch();
}
void cresc(int citire[20])
{
int i,temp;
for (i = 0;i < 9; i++)
{
if (citire[i] > citire[i + 1])
{
temp = citire[i];
citire[i] = citire[i + 1];
citire[i + 1] = temp;
}
fprintf(fpointer, "%d", citire[i]);
}
}
Can someone help me?
I manage to solve it, thanks for your help guys.
Here is the problem solved, if someone will need it.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <conio.h>
#include <string>
FILE *fpointer;
void cit(int citire[10]);
int paritate(int citire[10]);
void main()
{
char fisier[12];
int i, citire[10], trecere[10], nrpar;
printf("Dati un nume fisierului:");
scanf("%s", &fisier);
strcat(fisier, ".txt");
fpointer = fopen(fisier, "w");
fprintf(fpointer, "9 8 6 5 7 4 2 0 3 1");
fclose(fpointer);
fpointer = fopen(fisier, "r");
for (i = 0;i < 10;i++)
fscanf(fpointer, "%d", &citire[i]);
fclose(fpointer);
fpointer = fopen(fisier, "a");
fprintf(fpointer, "\nNumerele puse in ordine sunt: \n");
cit(citire);
nrpar = paritate(citire);
fprintf(fpointer, "\n\nSunt %d numere pare", nrpar);
fclose(fpointer);
_getch();
}
void cit(int citire[10])
{
int i,j, temp;
for (i = 0;i < 10; i++)
{
for (j = 0;j<9;j++)
if (citire[j] > citire[j + 1])
{
temp = citire[j];
citire[j] = citire[j + 1]; //9 8 6 5 7 4 2 0 3 1
citire[j + 1] = temp; //buble sort
}
}
for (i = 0;i < 10; i++)
fprintf(fpointer, " %d", citire[i]);
}
int paritate(int citire[10])
{
int i, par=0;
for (i = 0;i < 10; i++)
if (citire[i] % 2 == 0)
par ++;
return par;
}
You wright a string representing a single value to the file, you then read 9 integers from the file but there is a single value. You need to separate the values with a non numerical character, like this
fprintf(fpointer, "9 8 6 5 7 4 2 0 3 1");
and then to read, do this instead
while ((i < 9) && (fscanf(fpointer, "%d", &citire[i]) == 1))
++i;
Fix your cresc() function to make it take the number of elements as a parameter
void cresc(int *citire, int count);
and the for loop
for (i = 0 ; i < count ; ++i)
In your main() call cesc() like this
cresc(citere, i);

Resources