So for a recent USACO problem, the user had to read in a file with Row Col, for the first line, and then following that, lines with a series of either #'s or .'s . When using C to try this, I find that my array that stores the contents of the file is ending prematurely, midway through the 4th row of a 5 row file. There are no errors when executing.
#include <stdio.h>
int main()
{
FILE *fin = fopen("crosswords.in", "r");
FILE *fout = fopen("crosswords.out","w");
int N, M;
fscanf(fin,"%d %d", &N, &M);
int arr[N][M];
char c;
int i,j;
for (i = 0; i < N;i++) {
for (j = 0; j < M; j++) {
fscanf(fin,"%c", &c);
arr[i][j] = c;
printf("%c", c);
}
}
return 0;
}
That is the code. The file is:
5 3
...
#..
...
..#
.##
The output is:
...
#..
...
..
The first line is a newline, but the code block doesnt show it
Why does the code stop early?
EDITS:
When I print N and M, I get 5 and 3
I am using a 2d array because you have to perform calculations based on the position. The problem is: http://usaco.org/index.php?page=viewproblem2&cpid=488.
I also don't know how to respond to comments
\n is also a char and is read by fscanf. To skip \n try this:
fscanf(fin," %c", &c);
// ^A space before %c can skip any number of white-spaces
and use a printf("\n"); statement after the inner loop.
Related
Can anyone help me understand why the first char read from the file is dropped when I increase the file size to be > 19 rows?
When I run this with < 20 rows it works perfect, reads the input and dumps it. when I add a 20th row the first row of input drops the leading char when I print the array.
Im lost. :)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main () {
int i, j = 0;
FILE *pFile;
char string[20][12];
char file_contents_resultset[20][12];
pFile = fopen("sonar.txt", "r");
if (pFile == NULL)
{
printf ("error opening file");
return 0;
}
// Load 20 row of input into in an array and store a copy
for (i = 0; i < 20; i++)
{
fscanf (pFile, "%12s", &string[i]);
strcpy (file_contents_resultset[i], string[i]);
}
//Dump the first 5 rows of the array
printf ("Dump array contents \n");
for (i = 0; i < 5; i++)
{
for (j = 0; j < 12; j++)
{
printf ("%c", file_contents_resultset[i][j]);
}
printf ("\n");
}
fclose (pFile);
return 0;
};
This is my input file.
000110010001
101000110000
000110010111
100011100010
111001100001
001010001010
010100100101
011000010000
111111011010
001111011101
011011010010
001100010101
001010101100
000000000000
100010111111
100100110011
111100100001
011110001110
000110100101
011101111001
and this is the output
Dump array contents
00110010001
101000110000
000110010111
100011100010
111001100001
and this is the output if I delete the 20th row of input in the input file. Note the first char is no longer dropped.
Dump array contents
000110010001
101000110000
000110010111
100011100010
111001100001
Your one of the arrays you use for reading is redundant. You can use only string[][] or only file_contents_resultset[][].
I found that your problem is in the strcpy() call. Reading from the buffer is fine, but strcpy() seems to copy a blank character in the memory location of file_contents_resultset[0][0].
So to fix it by keeping as much of the program intact i did:
// ...
// stores only one row at a time
char string[12];
// ...
for (int i = 0; i < 20; i++) {
fscanf(pFile, "%12s", &string);
strcpy(file_contents_resultset[i], string);
}
// ...
}
If you want to be more concise and save memory, you can remove string altogether and just write:
// ...
// char string[12];
char file_contents_resultset[20][12];
// ...
// brackets in loops and other blocks can be omitted
// if the block is just 1 line long.
for (int i = 0; i < 20; i++)
fscanf(pFile, "%12s", &file_contents_resultset[20][12]);
// ...
I tried to scan and print the characters of array using below code but input characters are not matching with output characters
#include <stdio.h>
int main() {
char s[10];
int i, n;
printf("enter the value of n:\n");
scanf("%d", &n);
printf("start entering the characters:\n");
for (i = 0; i < n; i++) {
scanf("%c", &s[i]);
}
for (i = 0; i < n; i++) {
printf("%c", s[i]);
}
return 0;
}
OUTPUT
enter the value of n:
5
start entering the characters:
ABCDE(scanf values)
ABCD(printf values)
Can anyone please clarify my doubt why is the output not matching with input
Since you are wanting to read data into a character array with "scanf" you probably could just reference the string identifier instead and simplify things. Following are a few tweaks to your code that still inputs the data and prints it back out.
#include <stdio.h>
#include <string.h>
int main()
{
char s[10];
int i, n;
printf("enter the value of n:\n");
scanf("%d", &n);
printf("start entering the characters:\n");
scanf("%s", s); /* In lieu of using a loop */
if (strlen(s) < n) /* Just in case less characters are entered than was noted */
n = strlen(s);
for (i = 0; i < n; i++)
{
printf("%c", s[i]);
}
printf("\n");
return 0;
}
The program just scans in the complete string instead of a character at a time. Also, I included the "<string.h> file so as to use functions such as "strlen" (get the length of the string) to provide a bit more robustness to the code. Running the program netted the same character set that was entered.
:~/C_Programs/Console/InputOutput/bin/Release$ ./InputOutput
enter the value of n:
7
start entering the characters:
ABCDEFG
ABCDEFG
You might give that a try.
Regards.
I am trying to read a file and store each of its character in 2d array(of size 7 by 7) without special characters like '\n' and than print that 2d array.
I write a code but it does not store and print the last line characters in 2d array.
#include<stdio.h>
#include<stdlib.h>
int main()
{
char ar[7][7],c;
int i,j;
FILE *fp;
fp=fopen("B11.txt","r");
if(fp==NULL)
printf("File not Found");
for(i=0; i<7; i++)
{
for(j=0; j<7; j++)
{
fscanf(fp,"%c",&ar[i][j]);
}
}
for(i=0; i<7; i++)
{
for(j=0; j<7; j++)
{
printf("%c",ar[i][j]);
}
}
fclose(fp);
}
This the output of the my code:
abtvelo
camerag
bhtollp
qeryvxq
appboyl
awerfgh
But the file contains,
abtvelo
camerag
bhtollp
qeryvxq
appboyl
awerfgh
comsats
Here the file contains the word 'comsats' also, that is not printed. Why this word comsats is not printed?
for(i=0; i<7; i++)
{
for(j=0; j<7; j++)
{
fscanf(fp,"%c",&ar[i][j]);
}
}
ar[i][0] will have \n left out from previous line summing up to 7 \n thus ignoring last line.
change to
fscanf(fp," %c",&ar[i][j]);
or
have getchar() after inner for loop.
The \n character is causing the last line to be skipped.
Change this:
fscanf(fp,"%c",&ar[i][j]);
To this:
fscanf(fp," %c",&ar[i][j]);
^
The space consumes the newline character when using scanf() format specifiers such as %c %lf %d etc. The space is not needed however for reading strings, ( %s ).
Regarding your statement: without special characters like '\n'
If by this you are referring characters such as:
space (" ")
horizontal tab ("\t")
formfeed ("\f")
carriage return ("\r")
vertical tab ("\v")
and of course newline ("\n")
Consider replacing the fscanf() construct with one using fgetc() in conjunction with the white-space test function: isspace(). (which checks for those characters listed above.) Example:
#define ROW 7
#define COL 7
int main(void)
{
int row = 0;
int col = 0;
char ar[COL][ROW];
int byte;
FILE *fp = fopen(filename, "r");
if(fp)
{
byte = fgetc(fp);
while(byte != EOF)
{
if(!isspace(byte))
{ //populate array only if not white-space
ar[col][row++] = (char)byte;
if(row == ROW)
{
row = 0;
col++;
}
if(col == COL) break;
}
byte = fgetc(fp);
}
fclose(fp);
}
// print results as in your original post...
return 0;
}
I am trying to read this input txt file with my C code:
4 3
1.4 4.6 1
1.6 6.65 1
7.8 1.45 0
7 -2 2
and separate them into rows and columns so that I can sort. I tried doing that but I kept getting weird numbers.
So I tried printing out the rows and columns after I read them from the file and the output was zero. I realized then that my code is not reading the numbers from my text file properly. I have tried different means to fix to no avail. Any help or pointers will be highly appreciated.
#include <stdio.h>
#include <string.h>
#include <stdbool.h> //for bool
int main(){
setvbuf(stdout, NULL,_IONBF, 0);
int c;
FILE *file;
FILE *infile;
char filename[99];
char choice;
int rows, columns;
//while(choice == 'y' || choice == 'Y'){
printf("%s", "Enter file name: ");
fgets(filename, 99, stdin);
char *p = strchr(filename, '\n'); // p will point to the newline in filename
if(p) *p = 0;
file = fopen(filename, "r");
if (file) {
while ((c = getc(file)) != EOF)
putchar(c);
fclose(file);
}
else{
puts("FILE NOT FOUND");
}
//read rows and columns from file
printf("%s","\n");
fscanf(file, "%d", &rows);
fscanf(file, "%d", &columns);
printf("%d", rows);
printf("%d", columns);
}
Problem 1
int rows = 0;
int columns = 0;
float matrix[rows][columns];
float sumOfRows[rows];
is not right.
After that, the number of elements in matrix and sumOfRows is fixed. They won't change if you change the values of rows and columns later in your program.
You need to read the values of rows and columns first before you define matrix and sumOfRows.
Problem 2
fscanf(file, "%d", &matrix[rows][columns]);
printf("%f",matrix[rows][columns]);
are not right either. Given the defition of matrix, use of matrix[rows][columns] is not right. They access the array using out of bounds indices.
Remember that given an array of size N, the valid indices are 0 to N-1.
Here's one way to proceed to resolve your problems:
fscanf(file, "%d", &rows); // Use %d, not %f
fscanf(file, "%d", &columns); // Use %d, not %f
// Now define the arrays.
float matrix[rows][columns];
float sumOfRows[rows];
// Read the data of matrix
for (int i = 0; i < rows; ++i )
{
for (int j = 0; j < columns; ++j )
{
fscanf(file, "%f", &matrix[i][j]); // Use %f, not %d
}
}
Your problem (actually, two problems) are in the if (file) {... block. First, you use a loop to read all characters from the file. Because of that, at the end of the loop you are also at the end of the file. Any further calls to fscanf result in undefined behavior.
Second, if the file did not open, you print a message (to the wrong output) and still continue to the fscanf part, which definitely leads to undefined behavior.
Solution: Remove the while loop and fix the error handling code:
if(file) {
// Nothing!
} else {
perror(filename);
return 1; // or return EXIT_FAILURE;
}
i have a file like that :
1 100
2 200
3 300
4 400
1
i want to save it as a matrix and i want to save NULL if there is no second number !
i tried to write the program but it does not work correctly !
#include<stdio.h>
int main() {
int k=0 ,i,j , arr[100][100];
FILE *in= fopen("file.txt","r");
char line[1000];
while(fgets(line,1000,in) !=NULL) k++;
fgets(line,1000,in);
for (i=0;i<k;i++){
for (j=0;j<2;j++){
int tmp ;
fscanf(in ,"%d", &tmp) ;
arr[i][j] = tmp ;
}
}
fclose(in);
return 0; }
Two major problems:
The first is that the first loop will read all lines, even the one with the single number on the line. That means the lonely fgets call will not do anything, and more importantly that the value of k will be wrong.
The second problem is that once you read all data from the file, you don't go back to the beginning of the file, instead you continue to try and read from beyond the end of the file.
The first problem can be solve by skipping the second fgets call, and decreasing k by one.
The second problem can be solved by calling rewind after you counted the number of lines.
Also when you actually read the numbers, you don't need the inner loop, just do e.g.
scanf("%d %d", &arr[i][0], &arr[i][1]);
Actually, you don't need the first line-counting loop at all, you can do it all in a single loop, by using fgets and sscanf and then checking the return value of sscanf. So your program could look something like
#include <stdio.h>
int main(void)
{
int values[100][2];
FILE *input = fopen("file.txt", "r");
size_t entries = 0;
if (input != NULL)
{
char buffer[40];
while (fgets(buffer, sizeof(buffer), input) != NULL && entries < 100)
{
int res = sscanf(buffer, "%d %d", &values[entries][0], &values[entries][1]);
if (res <= 1 || res == EOF)
{
// Read the last line with only one number, or an error happened
values[entries][0] = 0;
values[entries][1] = 0;
break;
}
++entries;
}
if (ferror(input))
{
printf("Error reading file\n");
}
fclose(input);
}
// All done, the number of "records" or "entries" is in the variable entries
// Example code: print the values
for (size_t i = 0; i < entries; ++i)
printf("Line %d: %d %d\n", i + 1, values[i][0], values[i][1]);
return 0;
}