EDIT:
void print(const int *v, const int size) {
FILE *fpIn;
fpIn = fopen("char-array.txt", "a");
int i;
if (v != 0) {
for (i = 0; i < size; i++) {
printf("%d", (int)v[i]);
fprintf(fpIn, "%d\n", (int)v[i]);
}
perm_count++;
printf("\n");
}
fclose(fpIn);
}
I guess this is a relatively simple question :)
Basically the program is using a permutation algorithm, and printing the output to standard output in the console. I also want to write the content to a file via fprintf I assume. Though I cant seem to get it working. It just prints garbage characters into the first line in the text file and nothing more !
I will paste the code below, and help is much appreciated ! The write to file code is found within the print function.
Thanks,
T.
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <time.h>
#include <time.h>
clock_t startm, stopm;
#define START if ( (startm = clock()) == -1) {printf("Error calling clock");exit(1);}
#define STOP if ( (stopm = clock()) == -1) {printf("Error calling clock");exit(1);}
#define PRINTTIME printf("%2.3f seconds used by the processor.", ((double)stopm- startm)/CLOCKS_PER_SEC);
int perm_count = 0;
void print(const int *v, const int size) {
FILE *fpIn;
fpIn = fopen("char-array.txt", "wb");
int i;
if (v != 0) {
for (i = 0; i < size; i++) {
printf("%d", (char)v[i]);
fprintf(fpIn, "%d", v[i]);
fprintf(fpIn, "\n");
}
perm_count++;
printf("\n");
}
}
void permute(int *v, const int start, const int n) {
int i;
if (start == n-1) {
print(v, n);
}
else {
for (i = start; i < n; i++) {
int tmp = v[i];
v[i] = v[start];
v[start] = tmp;
permute(v, start+1, n);
v[start] = v[i];
v[i] = tmp;
}
}
}
int main() {
int i, x;
printf("Please enter the number of terms: ");
scanf("%d", &x);
int arr[x];
printf("Please enter the terms: ");
for(i = 0; i < x; i++)
scanf("%d", &arr[i]);
START
permute(arr, 0, sizeof(arr)/sizeof(int));
STOP
printf("Permutation Count: %d\n", perm_count);
PRINTTIME
return 0;
}
1. Incorrect access modes in fopen call
You open your file as a binary file: fopen("char-array.txt", "wb");. Don't put b to this string containing access modes if you are going to write formatted strings there. And since you probably want to append new data at the end of the file instead of overwritting them, use a instead of w:
fopen("char-array.txt", "a");
2. Writing to the output buffer, not directly into the file
When you are using functions like fprintf, you don't write directly to the file but to the output buffer. You have to use fflush to write data from the output buffer into the file, or you can just close your file by using fclose function which flushes this buffer automatically.
Just add this line:
fclose(fpIn);
at the end of print function.
3. Incorrect formatting of the output
You should not cast int to char. It will truncate your numbers. And you also have fprintf(fpIn, "\n"); in wrong scope I guess. It could look like this:
for (i = 0; i < size; i++) {
printf("%d ", v[i]);
fprintf(fpIn, "%d ", v[i]);
}
perm_count++;
printf("\n");
fprintf(fpIn, "\n");
Don't waste your time doing programming you don't have to, the use of fprintf is nice but since all you want to do is print the output, you can just print things into the file directly using UNIX built-in commands. Say your program is called wirteoutput then all you have to do is pass the following command when calling it from the shell writeoutput > file.txt. All you would have to use would be the printf function.
If you are curious about this, this is an old function and you can find a detailed description in the original paper The UNIX Operating System. Look at the section called Standard I/O.
You didn't cast to a char (from a int) when you wrote to the file as you did with the screen display. The following will provide the same numbers in the file as you're seeing on screen:
fprintf(fpIn, "%d", (char)v[i]);
Related
In C, there are many posts concerning using fgetc after fscanf, dealing with an additional \n, but I am seeing another issue when using them in the reverse order; fscanf after fgetc.
When using fscanf after fgetc, I get a different fscanf-result to if I just omit fgetc (in the example script, just hard-coding num=1000 and commenting-out the block using fgetc).
I can replicate this correct fscanf-result while still using fgetc if I rewrite the file contents to the myFile variable, as in the below script. Removing this line produces the different incorrect fscanf-result.
What is causing the difference in the fscanf-result when using fgetc first, and how can I address the issue?
/* First read tab-delimited 4-digit int data from a text file,
* parsing into an array of the correct size num, then compute
* the mean of the array while avoiding overflow. */
#include <stdio.h>
#include <stdlib.h>
int main(){
FILE *myFile;
myFile = fopen("int_values.txt", "r");
int c=0, i=0;
float mean = 0.0;
// Identifying there are 1000 values in the tab-delimited file.
// Using fgetc
int num = 1;
while ((c=fgetc(myFile)) != EOF ){
if (c == '\t')
++num;
}
int arr[num]; // Array of correct size for all values from file.
// Redeclaring since fgetc seems to break fscanf
myFile = fopen("int_values.txt", "r");
// Read and store each value from file to array.
for (i=0; i<num; i++){
fscanf(myFile, "%d ", &arr[i]);
}
// Compute average cumulatively to avoid overflow.
mean = arr[0]
for (i=1; i<num; i++){
//printf("In the %dth place, arr has value %d.\n", i, arr[i]);
mean *= (float)i / (float)(i+1);
mean += arr[i] / (float)(i+1);
}
fclose(myFile);
printf("The overall mean of the %d values in the file is %f.\n\n", num, mean);
return 0;
}
Identifying there are 1000 values in the tab-delimited file.
Do not count tabs. Instead, read the ints. It's far too easy for the number of tabs to not relate correctly to the number of int.
Sum the int into a long long to avoid overflow. Use double for generic floating-point math.
#include <stdio.h>
#include <stdlib.h>
int main(void) {
FILE *myFile = fopen("seal_weights.txt", "r");
if (myFile) {
int num = 0;
long long sum = 0;
int value;
// return 1 on success, EOF on end-of-file, else 0 on non-numeric input
while (fscanf(myFile, "%d", &value) == 1) {
sum += value;
num++;
}
double mean = num ? (double) sum / num : 0.0;
printf("The overall mean of the %d values in the file is %f.\n\n", num,
mean);
// read in again and save values if truly desired.
// This step not needed to compute average.
rewind(myFile);
int i;
int arr[num];
for (i = 0; i < num; i++) {
if (fscanf(myFile, "%d", &arr[i]) != 1) {
break;
}
}
// Use arr[] in some way.
fclose(myFile);
}
return 0;
}
It seems like I didn't quite understand how the file stream works. My text file right now contains the following integers: 1 10 5 4 2 3 -6, but I would like the program to be able to read any number of integers from the file, should it change.
Apparently I'm not even using the correct functions.
The code I have written is the following:
int main() {
printf("This program stores numbers from numeri.txt into an array.\n\n");
int a[100];
int num;
int count = 0;
FILE* numeri = fopen("numeri.txt", "r");
while (!feof(numeri)) {
num = getw(numeri);
a[count] = num;
if (fgetc(numeri) != ' ')
count++;
}
int i;
for (i = 0; i < count; i++) { printf("%d ", a[i]); }
return 0;
}
I would like it to print out the array with the stored numbers, but all I get is: 540287029 757084960 -1
Can someone help me understand what I did wrong and maybe tell me how to write this kind of code properly?
I have fixed your code based on comments. I used fscanf to read from file and limited the amount of numbers that can be stored in array by checking count < 100 and checking whether fscanf filled exactly one argument.
Also, I checked that whether file could be opened or not, just for safety. If it couldn't be opened, then just print error message and return 1.
int main() {
printf("This program stores numbers from numeri.txt into an array.\n\n");
int a[100] = {0};
int num;
int count = 0;
int i = 0;
FILE* numeri = fopen("numeri.txt", "r");
if (numeri == NULL) {
printf("Can't open file\n");
return 1;
}
while (count < 100 && fscanf(numeri, "%d", &num) == 1) {
a[count++] = num;
}
for (i = 0; i < count; i++) { printf("%d ", a[i]); }
return 0;
}
# include <stdio.h>
main()
{
FILE *fp;
int a[10], n, i;
char file_name[20];
printf("enter the file name \n");
scanf("%s", file_name);
printf("enter number of integers \n");
scanf("%d", &n);
fp = fopen(file_name, "rb");
if (fp == NULL) {
printf("Error in opening file \n");
return;
}
fread(a, 1, n, fp);
for (i = 0; i < n; i++) {
printf("%d \n", a[i]);
}
}
Output:
enter the file name /home/n/t1.txt enter number of integers
3 1540736144 1540736144 1540736144..
In file t1.txt , i have entered the intergers {10,20,30,40.50}
and stored in path /home/n/t1.txt..
But in output it is displaying some junk addresses..
Kindly guide me how to display the integers stored in file..
Your file is a text file, which is human-readabla and can be edited in text editors. You treat it like a binary file, which stores data in the same way it is stored in the memory. Such files are compact and fast to read, but not easily editable or readable by humans.
The C standard provides different functions to deal with these file types. fwrite and fread are for binary files. fprintf, fscanf, fgets and so on are for text files.
There are several ways to parse your input and SO is full of examples. A cheap way to read data is fscanf. It ignores new-lines and just treats them as white space. It is not a good way to read input if you have more complex data or if you need good eror handling, but for your small example, it will do. Your input doesn't seem to be organised in lines.
The code below defines the function scan_int, which reads a number of integers from a file. The main function shows how to use this function.
#include <stdlib.h>
#include <stdio.h>
/*
* Read at most max integers from a file and store them in arr.
* Return the number of integers read or -1 on file access error.
* Numbers may or may not be separated with commas.
*/
int scan_int(const char *fn, int arr[], int max)
{
FILE *f = fopen(fn, "r");
int n = 0;
if (f == NULL) return -1;
while (n < max && fscanf(f, "%d,", &arr[n]) == 1) n++;
fclose(f);
return n;
}
int main(void)
{
int a[10];
int i, n;
n = scan_int("data.txt", a, 10);
for (i = 0; i < n; i++) {
if (i) printf(", ");
printf("%d", a[i]);
}
printf("\n");
return 0;
}
I'm having trouble writing an array of double numbers in a text file. The problem is, the code runs, but doesn't write out anything.
#include <stdio.h>
#include <stdlib.h>
int main() {
FILE *out;
double numbers[30];
int i=0;
for(i;i<30;i++)
scanf("%lf", &numbers[i]);
out=fopen("out.txt", "w");
if (out == NULL) {
fprintf(stderr, "error in opening .txt");
exit(EXIT_FAILURE);
}
while ( i<30 ) {
fprintf(out, "%.3f", numbers[i]);
i++;
}
fclose(out);
return 0;
}
Basically, the code is supposed to write out an array of 30 double numbers in a text file, and round the decimals to '.3'.
You forgot to re-initialise i to 0, hence the current value of i is 30, which effectively causes the while loop to not execute.
i = 0; //Re-initialise i.
while ( i<30 ) {
fprintf(out, "%.3f", numbers[i]);
i++;
}
It would be better, if you use a for loop, as it's syntax helps you to remember to initialise the increment variable.
for (i = 0; i < 30; ++i)
fprintf(out, "%.3f", numbers[i]);
I'm working on a program for my Intro to C class that requires me to write a program that solves jumble puzzles (you know, those anagram puzzles you see in the newspaper), based on a dictionary text file that my professor gave us. It alphabetizes words from the dictionary, takes in jumbles from a text file (called "jumble.txt"), alphabetizes those, then runs a string compare to find a match. I've got all the code written, but it immediately crashes when I try to run it, and I can't figure out why. I thought maybe the Stackoverflow users might be able to help me out here.
Here's the code I have:
#include <stdio.h>
#include <strings.h>
#define MAX_WORD_LEN 6
#define MAX_NUM_WORDS 30000
typedef struct {
char word[MAX_WORD_LEN+1];
char sort[MAX_WORD_LEN+1];
} jumble_type;
void bubblesort(char letters[], int length);
int main () {
int words, jumbles;
int j, q;
jumble_type list[MAX_NUM_WORDS];
jumble_type list2[MAX_NUM_WORDS];
// Creating file pointers
FILE *ifp;
FILE *ifp2;
//Opens Jumble and dictionary files and reads the info from them
ifp = fopen("jumbledct.txt", "r");
ifp2 = fopen("jumble.txt", "r");
//Assigns the value of "words" to the first line of jumbledct.txt
fscanf(ifp, "%d", words);
//Assigns the value of "jumbles" to the first line of jumble.txt
fscanf(ifp2, "%d", jumbles);
// Reads the words from the dictionary into the "word" section of our
// list structure.
int i;
for (i = 0; i < words; i++){
fscanf(ifp, "%s", &list[i].word);
strcpy(list[i].sort, list[i].word);
bubblesort(list[i].sort, strlen(list[i].sort));
printf("%s\n", list[i].sort);
}
//Reads from Jumble.txt
for (i = 0; i < jumbles; i++){
fscanf (ifp2, "%s", &list2[i].word);
strcpy(list2[i].sort, list2[i].word);
bubblesort(list2[i].sort, strlen(list2[i].sort));
//printf("%s\n", list2[i].sort);
}
for(j=0;j<jumbles; j++){
printf("JUMBLE PUZZLE # %d: %s\n", j+1, list2[j].word);
int x=0;
for (q = 0; q < words; q++){
if(strcmp(list2[j].sort, list[q].sort)==0){
printf("%s\n", list[q].word);
x++;
}
}
if (x == 0){
printf("Sorry, this puzzle has no solutions. \n\n");
}
printf("\n");
}
return 0;
}
void bubblesort(char letters[], int length) {
char temp;
int x, y;
for(x = 0; x < length; x++){
for (y = x; y < length; y++){
if (letters[x] > letters[y]){
temp = letters[y];
letters[y] = letters[x];
letters[x] = temp;
}
}
}
}
Thanks in advance for all your help.
My C is a little rusty, but shouldn't the third argument to the fscanf function be an address (like &words and &jumbles)?