Redirecting input(text file) in C - c

so I can't seem to redirect an input so that my program reads it.
It says in the assignment that the program should NOT print anything to prompt for user input. As many numbers have to be read from stdin to test your programs, you are expected to use INPUT REDIRECTION to read the input from a file.
I have this main function:
int main(int argc, char const *argv[])
{
int arr[100];
for (int i = 0; i < SIZE; i++)
{
values[i] = 0;
hashMapLinear[i] = 0;
}
FILE* file = fopen("file_name.txt", "r");
int index = 0;
int k = 0;
while (!feof(file))
{
fscanf(file, "%d", &k);
arr[index] = k;
index++;
}
fclose(file);
file = fopen("file_name.txt", "r");
int i = 0;
fscanf(file, "%d", &i);
float size = i;
fscanf(file, "%d", &i);
int thresh_hold = i;
int load_factor = size / 2;
int j = 0;
if (size <= 0)
{
printf("\nSize of file can not be zero or negative integer:\n");
}
else
{
while (!feof(file))
{
if (num_keys <= load_factor)
{
int check_valid_input= fscanf(file, "%d", &i);
if (check_valid_input != 0 || check_valid_input== -1)
{
insert_into_hashtable(i, size);
}
else
{
printf("\n invalid input:\n");
exit(1);
}
}
else
{
printf("\nError in inserting more numbers:\n");
exit(1);
}
}
fclose(file);
printHashMap(arr,size, thresh_hold);
}
}
How do I edit this main function so that it redirects seq.1 or any other text file to the C program? Any help would be appreciated!

Simply use stdin instead of file, but do not open stdin, and do not close it.
When calling a program like ./program < seq.1, the operating system will pass the content of seq.1 to your program as if it were inputed through the console. Hence, using stdin, which represents console input, will do the job.
Note that stdin is by default already opened when your program starts.

Your code is hardcoding the input file, so file redirection from the command line will not do anything. File redirection helps with stdin (console input), stdout (console output), and stderr (console error message output). See linuxcommand.org here for a tutorial.
So to make your code work with stdin, use scanf instead of fscanf. scanf takes input from FILE stdin, whereas fscanf takes input from a specified FILE. Using scanf will result in input from stdin, which can be redirected on the command line as described above. Similarly, if you want to use stdout, use printf instead of fprintf. Neither scanf or printf take a file parameter, but are the same as fscanf and fprint in other respects. See this stackOverflow article for some more explanation.
Here is how I would fix your code to read/write to stdin and stdout:
#include <stdio.h>
int main(int argc, char const *argv[])
{
int arr[400];
for (int i = 0; i < SIZE_HASH_MAP; i++)
{
values[i] = 0;
hashMapLinear[i] = 0;
}
// Not Needed: FILE* file = fopen("file_name.txt", "r");
int index = 0;
int k = 0;
while (!feof(stdin))
{
scanf("%d", &k);
arr[index] = k;
index++;
}
// fclose(file);
// file = fopen("file_name.txt", "r");
int i = 0;
scanf("%d", &i);
float size = i;
//printf("%d ", i);
scanf("%d", &i);
int thresh_hold = i;
//printf("%d ", i);
int load_factor = size / 2;
int j = 0;
//int check_valid_input = 0;
if (size <= 0)
{
printf("\nSize of file can not be zero or negative integer:\n");
}
else
{
while (!feof(stdin))
{
if (num_keys <= load_factor)
{
int check_valid_input= scanf("%d", &i);
if (check_valid_input != 0 || check_valid_input== -1)
{
insert_into_hashtable(i, size);
}
else
{
printf("\n invalid input:\n");
exit(1);
}
}
else
{
printf("\nError in inserting more numbers:\n");
exit(1);
}
}
// fclose(file);
printHashMap(arr,size, thresh_hold);
}
}
To use stdin (and file redirection), you will not be able to close and reopen stdin and get the same data. It just does not work that way. So remove one of the read loops so you only read it once. The first loop reads it into array arr[], so the second loop should take the values from that array rather than re-reading it.
#include <stdio.h>
$include <stdlib.h>
int main(int argc, char const *argv[])
{
int arr[400];
for (int i = 0; i < SIZE_HASH_MAP; i++)
{
values [i] = 0;
hashMapLinear[i] = 0;
}
int index = 0;
int k = 0;
while (!feof(stdin))
{
scanf("%d", &k);
arr[index] = k;
index++;
}
float size = arr[0];
int thresh_hold = arr[1];
int load_factor = size / 2;
int j = 0;
if (size <= 0)
{
printf("\nSize of file can not be zero or negative integer:\n");
exit(-1);
}
else
{
int i;
for(i=2; i<index; i++) // reuse values stored in arr[]
insert_into_hashtable(arr[i], size);
printHashMap(arr,size, thresh_hold);
}
}

You may want to use open() instead of fopen(). Open returns a non-negative integer representing the lowest numbered unused file descriptor. With file descriptors it is much easier to redirect your output.

The shell command already redirects input to your program. There is a file pointer called stdin already opened in your program that represents the standard input. When you use < seq.1, it pipes the contents of the file in the standard input of your program, which you can read using fgetc or scanf.
int main(int argc, char const *argv[])
{
int arr[400];
for (int i = 0; i < SIZE_HASH_MAP; i++)
{
values[i] = 0;
hashMapLinear[i] = 0;
}
int index = 0;
int k = 0;
while (!feof(stdin))
{
fscanf(stdin, "%d", &k);
arr[index] = k;
index++;
}
}
This program reads all the numbers from the standard input and stores them in your array. Notice you don't need to open or close it, it is already open when your main is called and closed at the end of your program execution.

Related

Saving integers from a file into an array

I was hoping to get a bit of help, I am implementing an inversion counter algorithm to take in 50,000 intergers and display the inversions and time it took to run the algorithm, I am having a hard time allocating and saving the integers from the file into an array. My code complies and runs but nothing happens
here is what I have:
int main(int argc, char** argv)
{
int n, i;
int inversions=0;
int *A;
FILE *file;
char filename[100];
clock_t start, end;
double totalTime;
printf("Enter filename: ");
scanf("%s", filename);
file = fopen(filename, "r");
if(file == NULL)
{
printf("Error opening file!\n");
return 0;
}
fscanf(file, "%d", &n);
A = (int*) malloc(n * sizeof(int));
for(i = 0; i < n; i++) {
fscanf(file, "%d", &A[i]);
}
start = clock();
inversions = countInversionsBruteForce(A, n);
end = clock();
totalTime = (double) (end - start) / CLOCKS_PER_SEC;
printf("Brute Force Algorithm\n");
printf("Number of inversions: %d\n", inversions);
printf("Execution time: %f\n", totalTime);
I think I have noth allocated array size and saved it properly
Your program is incomplete so I was not able to compile it. Minimized the problem to just loading the data into your array:
Formatted code for readability.
Generated a suitable input file. Most likely this is your problem but you have not shared your input sample with us.
Added missing include files.
Remove argc, argv as you not using them.
Minimize scope of variables. Use size_t instead of int for unsigned values.
Max string size on obtaining file name
Check return value for scanf(), fopen(), fscanf().
Printing out the data read to demonstrate it's working.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main() {
printf("Enter filename: ");
char filename[100];
if(scanf("%99s", filename) != 1) {
printf("scanf failed\n");
return 1;
}
FILE *file = fopen(filename, "r");
if(!file) {
printf("Error opening file!\n");
return 1;
}
size_t n;
fscanf(file, "%zu", &n);
if(!n) {
printf("n must be positive");
return 1;
}
int *A = malloc(n * sizeof(*A));
for(size_t i = 0; i < n; i++)
if(fscanf(file, "%d", &A[i]) != 1) {
printf("fscanf() failed\n");
return 1;
}
printf("n = %zu\n", n);
printf("A = ");
for(size_t i = 0; i < n; i++)
printf("%d%s", A[i], i + 1 < n ? ", " : "\n");
}
with 1.txt as:
4
1
2
3
4
a sample session looks like this:
Enter filename: 1.txt
n = 4
A = 1, 2, 3, 4

fscanf not reading from a file containing asterisk characters

I tried to read a file containing an empty box of '*', the error message doesn't get printed, so the file is opened, but the scan doesn't work. I tried to print the count variable, and the value of count is 0. I don't really know where the fault is. Please help... Thanks
the file content that I want to read
int openmap(int file_no){
char filename[32];
char mapp[100][100];
int number;
int count;
int x[100];
int nomor = 1;
for(int i = 1; i <= file_no; i++){
sprintf(filename, "map%d.txt", i);
FILE *test = fopen(filename,"r");
if(test)
{
printf("%2d. Map %d\n", nomor, i);
x[nomor-1] = i;
nomor++;
fclose(test);
}else if(!test && i > file_no){
printf("No map available!");
return 1;
}
}
do{
printf("[0 to cancel] [1 - %d]>> ", nomor-1);
scanf("%d", &number);
}while(number < 0 || number > file_no);
if(number > 0){
sprintf(filename,"map%d.txt", x[number-1]);
printf("%s", filename);
FILE *open = fopen(filename, "r");
if(!open){
printf("error");
}
while(!feof){
fscanf(open, "%[^\n]\n", mapp[count]);
count++;
}
fclose(open);
for(int i = 0; i < count ; i++){
printf("%s\n", mapp[i]);
}
}
}
I created a small test program:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void main () {
char mapp[100][100];
int i, count = 0;
char filename[32];
sprintf(filename, "test.txt");
FILE *open = fopen(filename, "r");
if(!open){
printf("error");
}
while(!feof(open)){
fscanf(open, "%[^\n]\n", mapp[count]);
count++;
}
fclose(open);
for(i = 0; i < count ; i++){
printf("%s\n", mapp[i]);
}
}
as far as i can see the only issue you have regarding the relevant section is your while loop condition, you should use: while(!feof(open)) - i tested my solution and it works so it seems that this is the only issue in your solution

Fscanf Seg Error

Working on a project where I have to have a file that is generated numbers. First line is a generated int. Followed by a floats (separate lines). (I'm doing it separate lines because I feel it makes more sense as I have to read it two different ways for the bin packing problems which I need this for... Like one way of reading one at a time and another storing it in an array.. But want to get this down first)
Getting a seg fault when I try to read my file for a float after reading an int. Edit: Error occurs in readOffline.
int randomFunction()
{
FILE *fp;
int i;
fp = fopen("theItems.txt", "w" );
if (fp == NULL)
printf("Error: file can't be opened.\n");
srand(time(NULL) );
int random_number = rand();
printf("Random Number %d\n", random_number);
fprintf(fp,"%d",random_number);
fclose(fp);
fp = fopen("theItems.txt", "a");
int numberOfItems = rand();
printf("NumberOfItems: %d\n",numberOfItems);
for(i = 0; i < 10; i++)
{
fp = fopen("theItems.txt", "a");
float number = (float)rand()/(float)(RAND_MAX);
fprintf(fp,"%f",number);
fprintf(fp,"%s", "\n");
fclose(fp);
}
return numberOfItems;
}
void readOffline( int numberOfItems)
{
FILE *fp;
int n = 0,i;
float nu = 0.00;
fp = fopen("theItems.txt", "r");
if (fp == NULL)
printf("Error: file can't be opened.\n");
fseek(fp,SEEK_SET,0);
fscanf(fp,"%d",&n);
printf("Number read: %d\n", n);
float array[numberOfItems];
// for(i = 0; i < 3; i++)
// {
fscanf(fp,"%f",&nu);
// array[i] = nu;
// }
fclose(fp);
printf("Int:%d\n", n);
int j;
// for(j = 0; j < 3; j++)
// printf("Float Number:%f\n", array[j]);
}
int main()
{
int numberOfItems = randomFunction();
readOffline(numberOfItems);
return 0;
}
Just trying to get an understanding why it causes a seg error when I // it out I can get it to read my int but sometimes it isn't the right int read. But yeah.
Please let me know if I need any more details or need to be more clear anywhere
You have multiple issues in your code:
You open the output file multiple times in randomFunction(), you even leak a stream handle and leave it open.
You do not exit the function when fopen() returns NULL. The rest of the code invokes undefined behavior if fp == NULL.
The same problem is present in readOffline(): if fp == NULL, you should return from the function immediately.
you do not output a linefeed after the first random number in the output file.
you always output 10 random numbers.
most importantly: the random number returned by the randomFunction() is potentially huge, allocating an array with local storage larger than a few megabytes is likely to cause undefined behavior. Try and reduce the maximum random number of values.
Here is a proposed correction:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int randomFunction(void) {
FILE *fp;
int i;
fp = fopen("theItems.txt", "w");
if (fp == NULL) {
printf("Error: file can't be opened.\n");
return -1;
}
srand(time(NULL));
int random_number = rand();
printf("Random Number %d\n", random_number);
fprintf(fp, "%d\n", random_number);
int numberOfItems = 1 + rand() % 100; /* between 1 and 100 */
printf("NumberOfItems: %d\n", numberOfItems);
for (i = 0; i < numberOfItems; i++) {
float number = rand() / (float)(RAND_MAX);
fprintf(fp, "%f\n", number);
}
fclose(fp);
return numberOfItems;
}
void readOffline(int numberOfItems) {
FILE *fp;
int n = 0, i;
fp = fopen("theItems.txt", "r");
if (fp == NULL) {
printf("Error: file can't be opened.\n");
return;
}
fscanf(fp, "%d", &n);
printf("Number read: %d\n", n);
float array[numberOfItems];
for (i = 0; i < numberOfItems; i++) {
if (fscanf(fp, "%f", &array[i]) != 1)
break;
}
fclose(fp);
printf("Int:%d\n", n);
for (int j = 0; j < i; j++) {
printf("Float Number %d: %f\n", j, array[j]);
}
}
int main(void) {
int numberOfItems = randomFunction();
readOffline(numberOfItems);
return 0;
}
Note that I kept your semantics: the random number at the start of the file is not the number of floating point values that follow. I suspect it should be?
I would say that depending on the particular compiler that you are using, then this could be a problem in setting up the actual array. This is (as an example) discussed in Variable Sized Arrays vs calloc in C From the discussions, you should use calloc and free. Another point is that you need to make sure that your value is greater than 3 and not too big. Since the array is only in the local scope of readOffline(), you should not connect it to the variable numberOfItems.
float array[3];
for(i = 0; i < 3; i++)
{
fscanf(fp,"%f",&nu);
array[i] = nu;
}

issues using file with Xcode c

When I run this program with a file imported into Xcode, I receive an error of Thread 1: EXC_BAD_ACCESS (code=1 address=0x68) at the line c = fgetc(ptr);. I am not sure why fptr is null when it gets to this line. Any help would be great thanks.
#include <stdio.h>
#define M 100
#define N 100
char array[M][N] = {0};
void readFile();
void findStartandEnd();
void mazeTraversal();
int m = 0;
int n = 0;
int start[2] = {0};
int end[2] = {0};
int main() {
readFile();
//findStartandEnd();
//mazeTraversal();
}
void readFile() {
FILE *fptr;
char c;
char file_name[20];
int i, j;
printf("Please enter the size of the MxN maze.\n");
printf("Start with the M size then the N size follow each number by the return key.\n");
scanf("%d", &m);
scanf("%d", &n);
printf("Type in the name of the file containing the Field\n");
scanf("%s", file_name);
fptr = fopen(file_name, "r");
for (i = 0; i < M && i < m; i++)
for (j = 0; j < N && j < n; j++) {
c = fgetc(fptr);
while (!((c == '1') || (c =='0')))
c = fgetc(fptr);
array[i][j] = c;
}
fclose(fptr);
for (i = 0; i < M && i < m; i++)
for (j = 0; j < N && j < n; j++) {
if (j == 0) printf("\n");
printf("%c ", array[i][j]);
}
printf("\n");
}
You do not test if scanf correctly parsed a string into file_name. You do not even protect file_name from a potential buffer overflow with scanf("%19s", file_name);
Furthermore, you do not test whether fopen succeeded at opening the file. fptr could be NULL for many possible reasons, you must test that and fail gracefully.
Note that scanf will stop at the first white space character after the first word. Filenames with embedded spaces cannot be entered with this method.
Note also that c should be defined as int instead of char to properly test for end of file as EOF returned by fgetc() does not fit in a char.
You should also use braces around non trivial statements commended by the for loops. They are not strictly necessary, but it will avoid silly bugs when later amending your code.

Error when trying to read in numbers from txt file in C

I am new to C programming and I am getting a THREAD 1: EXC_BAD_ACCESS(code = 1, address 0x68)
when I run my program. The purpose of my code is to read from a txt file that contains positive and negative numbers and do something with it.
#include <stdio.h>
int main (int argc, const char * argv[]) {
FILE *file = fopen("data.txt", "r");
int array[100];
int i = 0;
int num;
while( fscanf(file, "%d" , &num) == 1) { // I RECEIVE THE ERROR HERE
array[i] = num;
printf("%d", array[i]);
i++;
}
fclose(file);
for(int j = 0; j < sizeof(array); j++){
printf("%d", array[j]);
}
}
After
FILE *file = fopen("data.txt", "r");
Say
if(file == 0) {
perror("fopen");
exit(1);
}
Just a guess, the rest of the code looks ok, so likely this is the problem.
Also worth noting that you might have more than 100 numbers in your file, in which case you will blow past the size of your array. Try replacing the while loop with this code:
for (int i = 0; i < 100 && ( fscanf(file, "%d" , &num) == 1); ++i)
{
array[i] = num;
printf("%d", array[i]);
}
Do you have the file "data.txt" created and local?
touch data.txt
echo 111 222 333 444 555 > data.txt
Check that your file open succeeded.
Here is a working version,
#include <stdio.h>
#include <stdlib.h> //for exit
int main (int argc, const char * argv[])
{
FILE *fh; //reminder that you have a file handle, not a file name
if( ! (fh= fopen("data.txt", "r") ) )
{
printf("open %s failed\n", "data.txt"); exit(1);
}
int array[100];
int idx = 0; //never use 'i', too hard to find
int num;
while( fscanf(fh, "%d" , &num) == 1) { // I RECEIVE THE ERROR HERE
array[idx] = num;
printf("%d,", array[idx]);
idx++;
}
printf("\n");
fclose(fh);
//you only have idx numbers (0..idx-1)
int jdx;
for(jdx = 0; jdx<idx; jdx++)
{
printf("%d,", array[jdx]);
}
printf("\n");
}

Resources